/*
 * A V4L2 driver for GalaxyCore gc2035 cameras.
 *
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <linux/clk.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-mediabus.h>
#include <linux/io.h>

#include "camera.h"

static unsigned int mclk = 0;
module_param(mclk, uint, 0);
MODULE_PARM_DESC(mclk,
"mclk override (default=0)");

static unsigned int frate = 0;
module_param(frate, uint, 0);
MODULE_PARM_DESC(frate,
"frate override (default=0)");

MODULE_AUTHOR("raymonxiu");
MODULE_AUTHOR("leonardo lontra");
MODULE_AUTHOR("@lex");
MODULE_DESCRIPTION("A low-level driver for GalaxyCore gc2035 sensors.");
MODULE_LICENSE("GPL");

//for internel driver debug
#define DEV_DBG_EN  0
#if(DEV_DBG_EN == 1)
#define vfe_dev_dbg(x,arg...) printk("[CSI_DEBUG][GC2035]"x,##arg)
#else
#define vfe_dev_dbg(x,arg...)
#endif

#define vfe_dev_err(x,arg...) printk("[CSI_ERR][GC2035]"x,##arg)
#define vfe_dev_print(x,arg...) printk("[CSI][GC2035]"x,##arg)

#define LOG_ERR_RET(x)  { \
                          int ret;  \
                          ret = x; \
                          if(ret < 0) {\
                            vfe_dev_err("error at %s\n",__func__);  \
                            return ret; \
                          } \
                        }

//define module timing
int MCLK = 24;
#define VREF_POL          V4L2_MBUS_VSYNC_ACTIVE_HIGH
#define HREF_POL          V4L2_MBUS_HSYNC_ACTIVE_HIGH
#define CLK_POL           V4L2_MBUS_PCLK_SAMPLE_RISING
#define REG_CLKRC         0xfa
#define V4L2_IDENT_SENSOR 0x2035

//define the voltage level of control signal
#define CSI_STBY_ON			1
#define CSI_STBY_OFF 		0
#define CSI_RST_ON			0
#define CSI_RST_OFF			1
#define CSI_PWR_ON			1
#define CSI_PWR_OFF			0

#define regval_list reg_list_a8_d8
#define REG_TERM 0xff
#define VAL_TERM 0xff
#define REG_DLY  0xff

/*
 * Our nominal (default) frame rate.
 */
int SENSOR_FRAME_RATE;
int N_WIN_SIZES;
static struct regval_list *sensor_default_regs;
static struct sensor_win_size *sensor_win_sizes;
int hres = 0;
struct sensor_resolutions_struct;
/*
 * The gc2035 sits on i2c with ID 0x78
 */
#define I2C_ADDR       0x78
#define SENSOR_NAME    "gc2035"
/*
 * Information we maintain about a known sensor.
 */
struct sensor_format_struct;  /* coming later */

struct cfg_array { /* coming later */
	struct regval_list * regs;
	int size;
};

static inline struct sensor_info *to_state(struct v4l2_subdev *sd)
{
  return container_of(sd, struct sensor_info, sd);
}

/*
 * The registers settings
 *
 */
 static struct regval_list sensor_default_regs_hres0[] =
 {
 	{0xfe,0x80},
 	{0xfe,0x80},
 	{0xfe,0x80},
 	{0xfc,0x06},
 	{0xf9,0xfe}, //[0] pll enable
 	{0xfa,0x00},
 	{0xf6,0x00},
 	{0xf7,0x17}, //pll enable
 	{0xf8,0x00},
 	{0xfe,0x00},
 	{0x82,0x00},
 	{0xb3,0x60},
 	{0xb4,0x40},
 	{0xb5,0x60},
 	{0x03,0x05},
 	{0x04,0x2e},

 	//measure window
 	{0xfe,0x00},
 	{0xec,0x04},
 	{0xed,0x04},
 	{0xee,0x60},
 	{0xef,0x90},

 	{0x0a,0x00}, //row start
 	{0x0c,0x02}, //col start

 	{0x0d,0x04},
 	{0x0e,0xc0},
 	{0x0f,0x06}, //Window setting
 	{0x10,0x58},//

 	{0x17,0x14}, //[0]mirror [1]flip
 	{0x18,0x0a}, //sdark 4 row in even frame??
 	{0x19,0x0a}, //AD pipe number

 	{0x1a,0x01}, //CISCTL mode4
 	{0x1b,0x48},
 	{0x1e,0x88}, //analog mode1 [7] tx-high en
 	{0x1f,0x0f}, //analog mode2

 	{0x20,0x05}, //[0]adclk mode  [1]rowclk_MODE [2]rsthigh_en
 	{0x21,0x0f}, //[3]txlow_en
 	{0x22,0xf0}, //[3:0]vref
 	{0x23,0xc3}, //f3//ADC_r
 	{0x24,0x16}, //pad drive

 	//==============================aec
 	//AEC
 	{0xfe,0x01},
 	{0x09,0x00},

 	{0x11,0x10},
 	{0x47,0x30},
 	{0x0b,0x90},
 	{0x13,0x80}, //0x75
 	{0x1f,0xc0},//addd
 	{0x20,0x50},//add  0x60
 	{0xfe,0x00},
 	{0xf7,0x17}, //pll enable
 	{0xf8,0x00},
 	{0x05,0x01},
 	{0x06,0x18},
 	{0x07,0x00},
 	{0x08,0x48},
 	{0xfe,0x01},
 	{0x27,0x00},
 	{0x28,0x6a},
 	{0x29,0x03},
 	{0x2a,0x50},//8fps
 	{0x2b,0x04},
 	{0x2c,0xf8},
 	{0x2d,0x06},
 	{0x2e,0xa0},//6fps
 	{0x3e,0x40},//0x40
 	{0xfe,0x00},
 	{0xb6,0x03}, //AEC enable
 	{0xfe,0x00},

 	///////BLK
 	{0x3f,0x00}, //prc close???
 	{0x40,0xa7}, // a7 77
 	{0x42,0x7f},
 	{0x43,0x30},//0x30

 	{0x5c,0x08},
 	//{0x6c  3a //manual_offset ,real B channel
 	//{0x6d  3a//manual_offset ,real B channel
 	//{0x6e  36//manual_offset ,real R channel
 	//{0x6f  36//manual_offset ,real R channel
 	{0x5e,0x20},
 	{0x5f,0x20},
 	{0x60,0x20},
 	{0x61,0x20},
 	{0x62,0x20},
 	{0x63,0x20},
 	{0x64,0x20},
 	{0x65,0x20},
 	{0x66,0x20},
 	{0x67,0x20},
 	{0x68,0x20},
 	{0x69,0x20},

 	/////crop//
 	{0x90,0x01},  //crop enable
 	{0x95,0x04},  //1600x1200
 	{0x96,0xb0},
 	{0x97,0x06},
 	{0x98,0x40},

 	{0xfe,0x03},
 	{0x42,0x80},
 	{0x43,0x06}, //output buf width //buf widthÕâÒ»¿éµÄÅäÖÃ»¹ÐèÒªžãÇå³þ
 	{0x41,0x00}, // delay
 	{0x40,0x00}, //fifo half full trig
 	{0x17,0x01}, //wid mipi²¿·ÖµÄ·ÖÆµÊÇÎªÊ²ÃŽv£¿
 	{0xfe,0x00},

 	{0x80,0xff},//block enable 0xff
 	{0x81,0x26},//38  //skin_Y 8c_debug

 	{0x03,0x05},
 	{0x04,0x2e},
 	{0x84,0x00}, //output put foramat
 	{0x86,0x03}, //sync plority
 	{0x87,0x80}, //middle gamma on
 	{0x8b,0xbc},//debug modeÐèÒªžãÇå³þÒ»ÏÂ
 	{0xa7,0x80},//B_channel_gain
 	{0xa8,0x80},//B_channel_gain
 	{0xb0,0x80}, //globle gain
 	{0xc0,0x40},

 #if 1
 	//lsc,
 	{0xfe,0x01},
 	{0xc2,0x10},//0x1f
 	{0xc3,0x02},//0x07
 	{0xc4,0x03},//0x03
 	{0xc8,0x10},//10
 	{0xc9,0x0a},//0x0a
 	{0xca,0x08},//0x08
 	{0xbc,0x16},//      3c
 	{0xbd,0x10},//0x1c
 	{0xbe,0x10},//0x1a
 	{0xb6,0x22},//    0x30
 	{0xb7,0x18},//0x1c
 	{0xb8,0x15},//0x15
 	{0xc5,0x00},
 	{0xc6,0x00},
 	{0xc7,0x00},
 	{0xcb,0x00},
 	{0xcc,0x00},
 	{0xcd,0x00},
 	{0xbf,0x0a},//0x0c
 	{0xc0,0x01},//0x04
 	{0xc1,0x00},
 	{0xb9,0x00},
 	{0xba,0x00},
 	{0xbb,0x00},
 	{0xaa,0x00},
 	{0xab,0x02},//00
 	{0xac,0x00},
 	{0xad,0x00},
 	{0xae,0x00},
 	{0xaf,0x00},
 	{0xb0,0x00},
 	{0xb1,0x00},
 	{0xb2,0x00},
 	{0xb3,0x00},
 	{0xb4,0x02},//00
 	{0xb5,0x00},
 	{0xd0,0x01},
 	{0xd2,0x02},//00
 	{0xd3,0x00},
 	{0xd8,0x18},
 	{0xda,0x00},
 	{0xdb,0x04},
 	{0xdc,0x00},
 	{0xde,0x07},//0x07
 	{0xdf,0x00},
 	{0xd4,0x00},
 	{0xd6,0x00},//00
 	{0xd7,0x00},
 	{0xa4,0x20},//00
 	{0xa5,0x02},//00
 	{0xa6,0x04},
 	{0xa7,0x00},
 	{0xa8,0x20},//00
 	{0xa9,0x02},//00
 	{0xa1,0x80},
 	{0xa2,0x80},

 	{0xfe,0x02},
 	{0xa4,0x00},
 	{0xfe,0x00},

 	{0xfe,0x02},
 	{0xc0,0x01},
 	{0xc1,0x40},  //Green_cc
 	{0xc2,0xfc},
 	{0xc3,0x05},
 	{0xc4,0xec},
 	{0xc5,0x42},
 	{0xc6,0xf8},
 	{0xc7,0x40},
 	{0xc8,0xf8},
 	{0xc9,0x06},
 	{0xca,0xfd},
 	{0xcb,0x3e},
 	{0xcc,0xf3},
 	{0xcd,0x36},
 	{0xce,0xf6},
 	{0xcf,0x04},
 	{0xe3,0x0c},
 	{0xe4,0x44},
 	{0xe5,0xe5},
 	{0xfe,0x00},
 	{0xfe,0x00},
 	//awb
 	{0xfe,0x01},
 	{0x4f,0x00},
 	{0x4d,0x10}, ////////////////10
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x20},  ///////////////20
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x30}, //////////////////30
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x02},  // d65
 	{0x4e,0x04},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x40},  //////////////////////40
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},  //cwf
 	{0x4e,0x08},  // cwf
 	{0x4e,0x04},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x50}, //////////////////50
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x10},  // tl84
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x60}, /////////////////60
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x70}, ///////////////////70
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x20},  // a
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x80}, /////////////////////80
 	{0x4e,0x00}, //H
 	{0x4e,0x40},  // h
 	{0x4e,0x00},  //A
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0x90}, //////////////////////90
 	{0x4e,0x00},  // h
 	{0x4e,0x40},
 	{0x4e,0x40},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xa0}, /////////////////a0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xb0}, //////////////////////////////////b0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xc0}, //////////////////////////////////c0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xd0}, ////////////////////////////d0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xe0}, /////////////////////////////////e0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4d,0xf0}, /////////////////////////////////f0
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4e,0x00},
 	{0x4f,0x01},
 #endif
 	{0xfe,0x01},
 	{0x50,0x88},
 	{0x52,0x40},
 	{0x54,0x60},
 	{0x56,0x06},
 	{0x57,0x20}, //pre adjust
 	{0x58,0x01},
 	{0x5c,0xf0},
 	{0x5d,0x40},
 	{0x5b,0x02}, //AWB_gain_delta
 	{0x61,0xaa},//R/G stand
 	{0x62,0xaa},//R/G stand
 	{0x71,0x00},
 	{0x74,0x10},  //AWB_C_max
 	{0x77,0x08},  //AWB_p2_x
 	{0x78,0xfd}, //AWB_p2_y
 	{0x86,0x30},
 	{0x87,0x00},
 	{0x88,0x06},//04
 	{0x8a,0x8a},//awb move mode
 	{0x89,0x75},
 	{0x84,0x08},  //auto_window
 	{0x8b,0x00},  //awb compare luma
 	{0x8d,0x70}, //awb gain limit R
 	{0x8e,0x70},//G
 	{0x8f,0xf4},//B
 	{0x5e,0xa4},
 	{0x5f,0x60},
 	{0x92,0x58},
 	{0xfe,0x00},
 	{0x82,0x02},//awb_en

 	//{0xfe ,0xec}, luma_value
 	{0xfe,0x01},
 	{0x1e,0xf1},
 	{0x9c,0x00}, //add abs slope 0x02
 	{0x21,0xbf},
 	{0xfe,0x02},
 	{0xa5,0x60}, //lsc_th //40
 	{0xa2,0xc0}, //lsc_dec_slope 0xa0
 	{0xa3,0x30}, //when total gain is bigger than the value, enter dark light mode  0x20 added
 	{0xa4,0x00},//add
 	{0xa6,0x50}, //dd_th
 	{0xa7,0x80}, //ot_th   30
 	{0xab,0x31}, //[0]b_dn_effect_dark_inc_or_dec
 	{0x88,0x15}, //[5:0]b_base
 	{0xa9,0x6c}, //[7:4] ASDE_DN_b_slope_high  0x6c 0x6f

 	{0xb0,0x66},  //6edge effect slope 0x66 0x88 0x99

 	{0xb3,0x70}, //saturation dec slope  //0x70   0x40
 	{0xb4,0x32},//0x32 0x42
 	{0x8c,0xf6}, //[2]b_in_dark_inc
 	{0x89,0x03}, //dn_c_weight 0x03

 	{0xde,0xb8},  //b6[7]asde_autogray [3:0]auto_gray_value  0xb9 0xb8  0xb9
 	{0x38,0x06},  //0aasde_autogray_slope 0x08 0x05 0x06 0x0a
 	{0x39,0x50},  //50asde_autogray_threshold  0x50     0x30

 	{0xfe,0x00},
 	{0x81,0x24}, //0x26
 	{0x87,0x90}, //[5:4]first_dn_en first_dd_en  enable 0x80 0xb0

 	{0xfe,0x02},
 	{0x83,0x00},//[6]green_bks_auto [5]gobal_green_bks
 	{0x84,0x45},//RB offset
 	{0xd1,0x38},  //saturation_cb  0x3a
 	{0xd2,0x38},  //saturation_Cr  0x38
 	{0xd3,0x30},
 	{0xdc,0x30},
 	{0xdd,0xb8},  //edge_sa_g,b
 	{0xfe,0x00},
 	{0xad,0x80},//80
 	{0xae,0x7d},//80
 	{0xaf,0x80},

 	//gmma-curve4-low strech
 	{0xfe,0x02},
 	{0x15,0x05},
 	{0x16,0x0b},
 	{0x17,0x10},
 	{0x18,0x16},
 	{0x19,0x24},
 	{0x1a,0x32},
 	{0x1b,0x42},
 	{0x1c,0x4e},
 	{0x1d,0x64},
 	{0x1e,0x76},
 	{0x1f,0x86},
 	{0x20,0x94},
 	{0x21,0x9f},
 	{0x22,0xb4},
 	{0x23,0xc3},
 	{0x24,0xce},
 	{0x25,0xd7},
 	{0x26,0xe3},
 	{0x27,0xec},
 	{0x28,0xf7},
 	{0x29,0xff},

 	//y-gamma
 	{0x2b,0x00},
 	{0x2c,0x04},
 	{0x2d,0x09},
 	{0x2e,0x18},
 	{0x2f,0x27},
 	{0x30,0x37},
 	{0x31,0x49},
 	{0x32,0x5c},
 	{0x33,0x7e},
 	{0x34,0xa0},
 	{0x35,0xc0},
 	{0x36,0xe0},
 	{0x37,0xff},
 	{0xfe,0x00},

 	{0xfe,0x00},

 	{0x82,0xfe},
 	//sleep  400
 	{0xf2,0x70},
 	{0xf3,0xff},
 	{0xf4,0x00},
 	{0xf5,0x30},
 	{0xfe,0x01},
 	{0x0b,0x90},
 	{0x87,0x00},//0x10
 	{0xfe,0x00},

 	/////,0xup},date
 	//ÈÈ?0x  },
 	{0xfe,0x02},
 	{0xa6,0x80}, //dd_th
 	{0xa7,0x60}, //ot_th //0x80
 	{0xa9,0x66}, //6f[7:4] ASDE_DN_b_slope_high 0x68
 	{0xb0,0x88},  //edge effect slope 0x99
 	{0x38,0x08},  //asde_autogray_slope 0x08   0x0f  0x0a 0b
 	{0x39,0x50},  //asde_autogray_threshold  0x60
 	{0xfe,0x00},
 	{0x87,0x90}, //[5:4]first_dn_en first_dd_en      0x90

 	{0xfe,0x00},
 	{0x90,0x01},
 	{0x95,0x01},
 	{0x96,0xe0},
 	{0x97,0x02},
 	{0x98,0x80},
 	{0xc8,0x14},
 	{0xf7,0x0D},
 	{0xf8,0x83},
 	{0xfa,0x00},//pll=4
 	{0x05,0x00},
 	{0x06,0xc4},
 	{0x07,0x00},
 	{0x08,0xae},
 	{0xad,0x80},
 	{0xae,0x7a},
 	{0xaf,0x7a},
 	{0xfe,0x01},
 	{0x27,0x00},
 	{0x28,0xe5},
 	{0x29,0x05},
 	{0x2a,0x5e},//18fps
 	{0x2b,0x07},
 	{0x2c,0x28},//12.5fps
 	{0x2d,0x0a},
 	{0x2e,0xbc},//8fps
 	{0x3e,0x40},// exposure level
 	{0xfe,0x03},
 	{0x42,0x04},
 	{0x43,0x05}, //output buf width
 	{0x41,0x02}, // delay
 	{0x40,0x40}, //fifo half full trig
 	{0x17,0x00}, //widv is 0
 	{0xfe,0x00},
 	{0xc8,0x55},
 };

 /* 1600X1200 UXGA capture */
 static struct regval_list sensor_uxga_regs_hres0[] =
 {
 	{0xfe , 0x00},
 	{0x0a , 0x00}, //row start
 	{0x0c , 0x00}, //col start

 	{0x0d , 0x04},
 	{0x0e , 0xc0},
 	{0x0f , 0x06}, //Window setting
 	{0x10 , 0x58},//

 	{0x90 , 0x01},  //crop enable
 	{0x94 , 0x04},//add
 	{0x95 , 0x04},
 	{0x96 , 0xb0},
 	{0x97 , 0x06},
 	{0x98 , 0x40},
 	{0x99 , 0x11},
 	{0xc8 , 0x00},

 	{0xfa , 0x11},

 	{0xfe , 0x03},
 	{0x42 , 0x80},
 	{0x43 , 0x06}, //output buf width
 	{0x41 , 0x00}, // delay
 	{0x40 , 0x00}, //fifo half full trig
 	{0x17 , 0x01}, //widv
 	{0xfe , 0x00},
 	{0xc8 , 0x00},
 };

 /* 1280X720 720HD */
 static struct regval_list Gc2015_sensor_hd720_regs_hres0[] =
 {
  {0xfe , 0x00},
  {0x05, 0x01},
  {0x06, 0x9e},
  {0x07, 0x01},
  {0x08, 0x6d},
  {0x0a , 0xf0}, //row start
  {0x0c , 0xa0}, //col start
  {0x0d , 0x02},
  {0x0e , 0xd8},
  {0x0f , 0x05}, //Window setting
  {0x10 , 0x18},

  {0xfe, 0x01},
  {0x27, 0x00},
  {0x28, 0xd9},
  {0x29, 0x04},
  {0x2a, 0x3d},//18fps
  {0x2b, 0x06},
  {0x2c, 0xc8},//12.5fps
  {0x2d, 0x0a},
  {0x2e, 0x2c},//8fps
  {0x3e, 0x40},//0x40 0x00

  //measure window
  {0xfe, 0x00},
  {0xec, 0x04},
  {0xed, 0x04},
  {0xee, 0x50},
  {0xef, 0x58},

  {0x90 , 0x01},  //crop enable
  {0x95 , 0x02},
  {0x96 , 0xd0},
  {0x97 , 0x05},
  {0x98 , 0x00},

  {0xfe , 0x03},
  {0x42 , 0x80},
  {0x43 , 0x06}, //output buf width
  {0x41 , 0x00}, // delay
  {0x40 , 0x00}, //fifo half full trig
  {0x17 , 0x01}, //widv
  {0xfe , 0x00},
  {0x99, 0x11},
  {0xc8, 0x00},
  {0xfa, 0x11},
  {0xff, 0xff},
 };

 /* 640X480 VGA */
 static struct regval_list sensor_vga_regs_hres0[] =
 {
   {0xfe , 0x00},

   {0x0a , 0x00}, //row start
   {0x0c , 0x00}, //col start

   {0x0d , 0x04},
   {0x0e , 0xc0},
   {0x0f , 0x06}, //Window setting
   {0x10 , 0x58},//

   {0x90 , 0x01},
   {0x94 , 0x00},
   {0x95 , 0x01},
   {0x96 , 0xe0},
   {0x97 , 0x02},
   {0x98 , 0x80},
   {0xc8 , 0x15},

   {0xfa , 0x00},

   {0xfe , 0x03},
   {0x42 , 0x00},
   {0x43 , 0x05}, //output buf width  280*2=500
   {0x41 , 0x02}, // delay
   {0x40 , 0x40}, //fifo half full trig
   {0x17 , 0x00}, //widv is 0

   {0xfe , 0x00},
   {0xc8 , 0x55},
   {0xb6 , 0x03},//aec on
 };

 static struct regval_list sensor_default_regs_hres1[] = {
 {0xfe , 0x80},
 {0xfe , 0x80},
 {0xfe , 0x80},
 {0xfc , 0x06},
 {0xf2 , 0x00},
 {0xf3 , 0x00},
 {0xf4 , 0x00},
 {0xf5 , 0x00},
 {0xf9 , 0xfe}, //[0] pll enable
 {0xfa , 0x00},
 {0xf6 , 0x00},
 {0xf7 , 0x15}, //pll enable

 {0xf8 , 0x85},
 {0xfe , 0x00},
 {0x82 , 0x00},
 {0xb3 , 0x60},
 {0xb4 , 0x40},
 {0xb5 , 0x60},

 {0x03 , 0x02},
 {0x04 , 0x80},

 //////////measure window  ///////////
 {0xfe , 0x00},
 {0xec , 0x06},//04
 {0xed , 0x06},//04
 {0xee , 0x62},//60
 {0xef , 0x92},//90

 ///////////analog/////////////
 {0x0a , 0x00}, //row start
 {0x0c , 0x00}, //col start
 {0x0d , 0x04},
 {0x0e , 0xc0},
 {0x0f , 0x06}, //Window setting
 {0x10 , 0x58},
 {0x17 , 0x14}, //[0]mirror [1]flip
 {0x18 , 0x0a}, //0a 2012.10.26
 {0x19 , 0x0a}, //AD pipe number

 {0x1a, 0x01}, //CISCTL mode4
 {0x1b , 0x8b},
 {0x1c , 0x05}, //added
 {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias
 {0x1f , 0x08}, //[3] tx-low en//
 {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en
 {0x21 , 0x0f}, //[6:4]rsg
 {0x22 , 0xf0}, //[3:0]vref   0xf0
 {0x23 , 0xc3}, //f3//ADC_r
 {0x24 , 0x15}, //pad drive <=36MHz, use 0x00 is ok

 //AEC
 {0xfe , 0x01},
 {0x11 , 0x20},//AEC_out_slope , 0x
 {0x1f , 0xa0},//max_post_gain
 {0x20 , 0x40},//max_pre_gain
 {0x47 , 0x30},//AEC_outdoor_th
 {0x0b , 0x10},//
 {0x13 , 0x75},//y_target
 {0xfe , 0x00},

 {0x05 , 0x01},//hb
 {0x06 , 0x11},
 {0x07 , 0x00},//vb
 {0x08 , 0x50},
 {0xfe , 0x01},
 {0x27 , 0x00},//step
 {0x28 , 0xa0},
 {0x29 , 0x05},//level1
 {0x2a , 0x00},
 {0x2b , 0x05},//level2
 {0x2c , 0x00},
 {0x2d , 0x06},//6e8//level3
 {0x2e , 0xe0},
 {0x2f , 0x0a},//level4
 {0x30 , 0x00},
 {0x3e  , 0x40},
 {0xfe , 0x00},
 {0xfe , 0x00},  //0x , 0x , 0x , 0x , 0x
 {0xb6 , 0x03}, //AEC enable
 {0xfe , 0x00},

 /////////BLK//////
 {0x3f , 0x00}, //prc close
 {0x40 , 0x77},//
 {0x42 , 0x7f},
 {0x43 , 0x30},
 {0x5c , 0x08},
 {0x5e , 0x20},
 {0x5f , 0x20},
 {0x60 , 0x20},
 {0x61 , 0x20},
 {0x62 , 0x20},
 {0x63 , 0x20},
 {0x64 , 0x20},
 {0x65 , 0x20},

 ///block////////////
 {0x80 , 0xff},
 {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug
 {0x87 , 0x90}, //[7]middle gamma
 {0x84 , 0x02}, //output put foramat
 {0x86 , 0x07}, //02 //sync plority
 {0x8b , 0xbc},
 {0xb0 , 0x80}, //globle gain
 {0xc0 , 0x40},//Yuv bypass

 //////lsc/////////////
 {0xfe , 0x01},
 {0xc2 , 0x38},
 {0xc3 , 0x25},
 {0xc4 , 0x21},
 {0xc8 , 0x19},
 {0xc9 , 0x12},
 {0xca , 0x0e},
 {0xbc , 0x43},
 {0xbd , 0x18},
 {0xbe , 0x1b},
 {0xb6 , 0x40},
 {0xb7 , 0x2e},
 {0xb8 , 0x26},
 {0xc5 , 0x05},
 {0xc6 , 0x03},
 {0xc7 , 0x04},
 {0xcb , 0x00},
 {0xcc , 0x00},
 {0xcd , 0x00},
 {0xbf , 0x14},
 {0xc0 , 0x22},
 {0xc1 , 0x1b},
 {0xb9 , 0x00},
 {0xba , 0x05},
 {0xbb , 0x05},
 {0xaa , 0x35},
 {0xab , 0x33},
 {0xac , 0x33},
 {0xad , 0x25},
 {0xae , 0x22},
 {0xaf , 0x27},
 {0xb0 , 0x1d},
 {0xb1 , 0x20},
 {0xb2 , 0x22},
 {0xb3 , 0x14},
 {0xb4 , 0x15},
 {0xb5 , 0x16},
 {0xd0 , 0x00},
 {0xd2 , 0x07},
 {0xd3 , 0x08},
 {0xd8 , 0x00},
 {0xda , 0x13},
 {0xdb , 0x17},
 {0xdc , 0x00},
 {0xde , 0x0a},
 {0xdf , 0x08},
 {0xd4 , 0x00},
 {0xd6 , 0x00},
 {0xd7 , 0x0c},
 {0xa4 , 0x00},
 {0xa5 , 0x00},
 {0xa6 , 0x00},
 {0xa7 , 0x00},
 {0xa8 , 0x00},
 {0xa9 , 0x00},
 {0xa1 , 0x80},
 {0xa2 , 0x80},

 //////////cc//////////////
 {0xfe , 0x02},
 {0xc0 , 0x01},
 {0xc1 , 0x40}, //Green_cc for d
 {0xc2 , 0xfc},
 {0xc3 , 0x05},
 {0xc4 , 0xec},
 {0xc5 , 0x42},
 {0xc6 , 0xf8},
 {0xc7 , 0x40},//for cwf
 {0xc8 , 0xf8},
 {0xc9 , 0x06},
 {0xca , 0xfd},
 {0xcb , 0x3e},
 {0xcc , 0xf3},
 {0xcd , 0x36},//for A
 {0xce , 0xf6},
 {0xcf , 0x04},
 {0xe3 , 0x0c},
 {0xe4 , 0x44},
 {0xe5 , 0xe5},
 {0xfe , 0x00},

 ///////awb start ////////////////
 //AWB clear
 {0xfe , 0x01},
 {0x4f , 0x00},
 {0x4d , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x10}, // 10
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x20}, // 20
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x30},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00}, // 30
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x40}, // 40
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x50}, // 50
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x60}, // 60
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x70}, // 70
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x80}, // 80
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x90}, // 90
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xa0}, // a0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xb0}, // b0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xc0}, // c0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xd0}, // d0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4f , 0x01},
 /////// awb value////////
 {0xfe , 0x01},
 {0x4f , 0x00},
 {0x4d , 0x30},
 {0x4e , 0x00},
 {0x4e , 0x80},
 {0x4e , 0x80},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4d , 0x40},
 {0x4e , 0x00},
 {0x4e , 0x80},
 {0x4e , 0x80},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4d , 0x53},
 {0x4e , 0x08},
 {0x4e , 0x04},
 {0x4d , 0x62},
 {0x4e , 0x10},
 {0x4d , 0x72},
 {0x4e , 0x20},
 {0x4f , 0x01},

 /////awb////
 {0xfe , 0x01},
 {0x50 , 0x88},//c0//[6]green mode
 {0x52 , 0x40},
 {0x54 , 0x60},
 {0x56 , 0x06},
 {0x57 , 0x20}, //pre adjust
 {0x58 , 0x01},
 {0x5b , 0x02}, //AWB_gain_delta
 {0x61 , 0xaa},//R/G stand
 {0x62 , 0xaa},//R/G stand
 {0x71 , 0x00},
 {0x74 , 0x10},  //0x//AWB_C_max
 {0x77 , 0x08}, // 0x//AWB_p2_x
 {0x78 , 0xfd}, //AWB_p2_y
 {0x86 , 0x30},
 {0x87 , 0x00},
 {0x88 , 0x04},//06 , 0x//[1]dark mode
 {0x8a , 0xc0},//awb move mode
 {0x89 , 0x75},
 {0x84 , 0x08},  //0x//auto_window
 {0x8b , 0x00}, // 0x//awb compare luma
 {0x8d , 0x70}, //awb gain limit R
 {0x8e , 0x70},//G
 {0x8f , 0xf4},//B
 {0xfe , 0x00},
 {0x82 , 0x02},//awb_en
 /////////awb end /////////////

 ///==========asde
 {0xfe , 0x01},
 {0x21 , 0xbf},
 {0xfe , 0x02},
 {0xa4 , 0x00},//
 {0xa5 , 0x40}, //lsc_th
 {0xa2 , 0xa0}, //lsc_dec_slope
 {0xa6 , 0x80}, //dd_th
 {0xa7 , 0x80}, //ot_th
 {0xab , 0x31}, //
 {0xa9 , 0x6f}, //
 {0xb0 , 0x99}, //0x//edge effect slope low
 {0xb1 , 0x34},//edge effect slope low
 {0xb3 , 0xf0}, //saturation dec slope
 {0xde , 0xb6},  //
 {0x38 , 0x0f}, //
 {0x39 , 0x60}, //
 {0xfe , 0x00},
 {0x81 , 0x26},
 {0xfe , 0x02},
 {0x83 , 0x00},//
 {0x84 , 0x45},//
 ////////////YCP//////////
 {0xd1 , 0x34},//saturation_cb
 {0xd2 , 0x34},//saturation_Cr
 {0xd3 , 0x40},//contrast ?	{0xd4 , 0x80},//contrast center
 {0xd4  , 0x80},//contrast center
 {0xd5 , 0x00},//luma_offset
 {0xdc , 0x30},
 {0xdd , 0xb8},//edge_sa_g,b
 {0xfe , 0x00},
 ///////dndd///////////
 {0xfe , 0x02},
 {0x88 , 0x15},//dn_b_base
 {0x8c , 0xf6}, //[2]b_in_dark_inc
 {0x89 , 0x03}, //dn_c_weight
 ////////EE ///////////
 {0xfe , 0x02},
 {0x90 , 0x6c},// EEINTP mode1
 {0x97 , 0x45},// edge effect
 ////==============RGB Gamma
 {0xfe , 0x02},
 {0x15 , 0x0a},
 {0x16 , 0x12},
 {0x17 , 0x19},
 {0x18 , 0x1f},
 {0x19 , 0x2c},
 {0x1a , 0x38},
 {0x1b , 0x42},
 {0x1c , 0x4e},
 {0x1d , 0x63},
 {0x1e , 0x76},
 {0x1f , 0x87},
 {0x20 , 0x96},
 {0x21 , 0xa2},
 {0x22 , 0xb8},
 {0x23 , 0xca},
 {0x24 , 0xd8},
 {0x25 , 0xe3},
 {0x26 , 0xf0},
 {0x27 , 0xf8},
 {0x28 , 0xfd},
 {0x29 , 0xff},

 ///=================y gamma
 {0xfe , 0x02},
 {0x2b , 0x00},
 {0x2c , 0x04},
 {0x2d , 0x09},
 {0x2e , 0x18},
 {0x2f , 0x27},
 {0x30 , 0x37},
 {0x31 , 0x49},
 {0x32 , 0x5c},
 {0x33 , 0x7e},
 {0x34 , 0xa0},
 {0x35 , 0xc0},
 {0x36 , 0xe0},
 {0x37 , 0xff},
 /////1600x1200size//
 {0xfe , 0x00},//
 {0x90 , 0x01}, //0x//crop enable
 {0x94 , 0x04},
 {0x95 , 0x04},  //0x//1600x1200
 {0x96 , 0xb0},
 {0x97 , 0x06},
 {0x98 , 0x40},

 {0xfe , 0x03},
 {0x42 , 0x40},
 {0x43 , 0x06}, //output buf width
 {0x41 , 0x02}, // Pclk_polarity
 {0x40 , 0x40},  //00
 {0x17 , 0x00}, //widv
 {0xfe , 0x00},
 ////output DVP/////
 {0xfe  , 0x00},
 {0x82  , 0xfe},  // fe
 {0xf2  , 0x70},
 {0xf3  , 0xff},
 {0xf4  , 0x00},
 {0xf5  , 0x30},
     ////////sabsumple  800X600//////
 {0xfe , 0x00},
 {0xb6 , 0x03},
 {0xfa , 0x00},

 {0xc8  , 0x00},//close scaler
 {0x99  , 0x22},// 1/2 subsample
 {0x9a , 0x07},
 {0x9b  , 0x00},
 {0x9c  , 0x00},
 {0x9d  , 0x00},
 {0x9e  , 0x00},
 {0x9f  , 0x00},
 {0xa0  , 0x00},
 {0xa1  , 0x00},
 {0xa2  , 0x00},

 {0x90  , 0x01},  //crop enable
 {0x95  , 0x02},
 {0x96  , 0x58},
 {0x97  , 0x03},
 {0x98  , 0x20},

 #if 1
 /////////  re zao///
 {0xfe  , 0x00},
 {0x22  , 0xf0},
 {0xfe  , 0x01},
 {0x21  , 0xff},
 {0xfe  , 0x02},
 {0x8a  , 0x33},
 {0x8c  , 0x76},
 {0x8d  , 0x85},
 {0xa6  , 0xf0},
 {0xae  , 0x9f},
 {0xa2  , 0x90},
 {0xa5  , 0x40},
 {0xa7  , 0x30},
 {0xb0  , 0x88},
 {0x38  , 0x0b},
 {0x39  , 0x30},
 {0xfe  , 0x00},
 {0x87  , 0xb0},

 //// small  RGB gamma////
 /*
 {0xfe , 0x02},
 {0x15 , 0x0b},
 {0x16 , 0x0e},
 {0x17 , 0x10},
 {0x18 , 0x12},
 {0x19 , 0x19},
 {0x1a , 0x21},
 {0x1b , 0x29},
 {0x1c , 0x31},
 {0x1d , 0x41},
 {0x1e , 0x50},
 {0x1f , 0x5f},
 {0x20 , 0x6d},
 {0x21 , 0x79},
 {0x22 , 0x91},
 {0x23 , 0xa5},
 {0x24 , 0xb9},
 {0x25 , 0xc9},
 {0x26 , 0xe1},
 {0x27 , 0xee},
 {0x28 , 0xf7},
 {0x29 , 0xff},
 */
 ////dark sun/////
 {0xfe , 0x02},
 {0x40 , 0x06},
 {0x41 , 0x23},
 {0x42 , 0x3f},
 {0x43 , 0x06},
 {0x44 , 0x00},
 {0x45 , 0x00},
 {0x46 , 0x14},
 {0x47 , 0x09},
 {0xfe , 0x00},
 #endif
 };

 /* 1600X1200 UXGA capture */
 static struct regval_list sensor_uxga_regs_hres1[] =
 {
 {0xfe , 0x00},
 {0xfa , 0x11},
 {0xc8 , 0x00},

 {0x99 , 0x11},// 1/2 subsample
 {0x9a , 0x06},
 {0x9b , 0x00},
 {0x9c , 0x00},
 {0x9d , 0x00},
 {0x9e , 0x00},
 {0x9f , 0x00},
 {0xa0 , 0x00},
 {0xa1 , 0x00},
 {0xa2 , 0x00},

 {0x90 , 0x01},
 {0x95 , 0x04},
 {0x96 , 0xb0},
 {0x97 , 0x06},
 {0x98 , 0x40},
 };

 /* 800X600 SVGA,30fps*/
 static struct regval_list sensor_svga_regs_hres1[] =
 {
 {0xfe,0x00},
 {0xb6,0x03},
 {0xfa , 0x00},
 {0xc8,0x00},//close scaler

 {0x99,0x22},// 1/2 subsample
 {0x9a , 0x07},
 {0x9b,0x00},
 {0x9c,0x00},
 {0x9d,0x00},
 {0x9e,0x00},
 {0x9f,0x00},
 {0xa0,0x00},
 {0xa1,0x00},
 {0xa2,0x00},

 {0x90,0x01},  //crop enable
 {0x95,0x02},
 {0x96,0x58},
 {0x97,0x03},
 {0x98,0x20},
 };

 static struct regval_list sensor_default_regs_hres3[] =
 {
 {0xfe , 0x80},
 {0xfe , 0x80},
 {0xfe , 0x80},
 {0xfc , 0x06},
 {0xf2 , 0x00},
 {0xf3 , 0x00},
 {0xf4 , 0x00},
 {0xf5 , 0x00},
 {0xf9 , 0xfe}, //[0] pll enable
 {0xfa , 0x00},
 {0xf6 , 0x00},
 {0xf7 , 0x15}, //pll enable

 {0xf8 , 0x85},

 {0xfe , 0x00},
 {0x82 , 0x00}, //00
 {0xb3 , 0x60}, //60
 {0xb4 , 0x40}, //60 40
 {0xb5 , 0x60}, //60

 {0x03 , 0x02},
 {0x04 , 0x80},

 //////////measure window  ///////////
 {0xfe , 0x00},
 {0xec , 0x06},//04
 {0xed , 0x06},//04
 {0xee , 0x62},//60
 {0xef , 0x92},//90

 ///////////analog/////////////
 {0x0a , 0x00}, //row start
 {0x0b , 0x10}, //row start
 {0x0c , 0x00}, //col start
 {0x0d , 0x04}, //4d0 = 1232
 {0x0e , 0xe0}, //d0/b0/d0/c0
 {0x0f , 0x06}, //Window setting
 {0x10 , 0x58}, //40/50/58
 {0x17 , 0x14}, //[0]mirror [1]flip [4]better colour


 //{0x18 , 0x0a}, //0a 2012.10.26
 {0x18 , 0x0f}, //0a 2012.10.26
 {0x19 , 0x0a}, //AD pipe number

 {0x1a , 0x01}, //CISCTL mode4
 {0x1b , 0x8b},
 {0x1c , 0x05}, //added
 {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias
 {0x1f , 0x08}, //[3] tx-low en//
 {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en
 {0x21 , 0x0f}, //[6:4]rsg
 {0x22 , 0xf0}, //[3:0]vref   0xf0
 {0x23 , 0xc3}, //f3//ADC_r
 {0x24 , 0x17}, //pad drive <=36MHz, use 0x00 is ok

 //AEC
 {0xfe , 0x01},
 {0x11 , 0x20},//20 AEC_out_slope , 0x
 {0x1f , 0xc0},//80 max_post_gain
 {0x20 , 0x60},//40 max_pre_gain
 {0x47 , 0x80},//30 AEC_outdoor_th
 {0x0b , 0x13},//10
 {0x13 , 0x75},//y_target
 {0xfe , 0x00},

 {0xfe , 0x00},
 {0xfe , 0x00},
 {0x05 , 0x01},//hb
 {0x06 , 0x0d},
 {0x07 , 0x00},//vb
 {0x08 , 0x40},

 {0xfe , 0x01},
 {0x27 , 0x00},//step
 {0x28 , 0xa0},//a0
 {0x29 , 0x05},//  level 0 12.5
 {0x2a , 0x00},
 {0x2b , 0x05},//  level 1 12.5
 {0x2c , 0x00},
 {0x2d , 0x05},//  level 2 12.5 640/10fps
 {0x2e , 0x00},
 {0x2f , 0x08},//  level 3 7.5
 {0x30 , 0x20},

 {0xfe , 0x00},
 {0xfe , 0x00},  //0x , 0x , 0x , 0x , 0x
 {0xb6 , 0x03}, //AEC enable
 {0xfe , 0x00},

 /////////BLK//////
 {0x3f, 0x00}, //prc close
 {0x40, 0x77},//
 {0x42, 0x7f},
 {0x43, 0x30},
 {0x5c, 0x08},
 {0x5e, 0x20},
 {0x5f, 0x20},
 {0x60, 0x20},
 {0x61, 0x20},
 {0x62, 0x20},
 {0x63, 0x20},
 {0x64, 0x20},
 {0x65, 0x20},

 ///block////////////
 {0x80 , 0xff},
 {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug
 {0x87 , 0x90}, //[7]middle gamma
 {0x84 , 0x02}, //output put foramat
 {0x86 , 0x07}, //02 //sync plority
 {0x8b , 0xbc},
 {0xb0 , 0x80}, //globle gain
 {0xc0 , 0x40},//Yuv bypass

 //////lsc/////////////
 {0xfe,0x01},
 {0xc2,0x21},
 {0xc3,0x1a},
 {0xc4,0x13},
 {0xc8,0x17},
 {0xc9,0x0f},
 {0xca,0x00},
 {0xbc,0x36},
 {0xbd,0x2b},
 {0xbe,0x17},
 {0xb6,0x39},
 {0xb7,0x21},
 {0xb8,0x1c},
 {0xc5,0x00},
 {0xc6,0x00},
 {0xc7,0x00},
 {0xcb,0x00},
 {0xcc,0x0c},
 {0xcd,0x15},
 {0xbf,0x00},
 {0xc0,0x00},
 {0xc1,0x00},
 {0xb9,0x00},
 {0xba,0x00},
 {0xbb,0x00},
 {0xaa,0x15},
 {0xab,0x15},
 {0xac,0x15},
 {0xad,0x14},
 {0xae,0x13},
 {0xaf,0x12},
 {0xb0,0x1b},
 {0xb1,0x14},
 {0xb2,0x14},
 {0xb3,0x1f},
 {0xb4,0x12},
 {0xb5,0x13},
 {0xd0,0x00},
 {0xd2,0x00},
 {0xd3,0x0c},
 {0xd8,0x00},
 {0xda,0x00},
 {0xdb,0x13},
 {0xdc,0x00},
 {0xde,0x00},
 {0xdf,0x25},
 {0xd4,0x00},
 {0xd6,0x00},
 {0xd7,0x12},
 {0xa4,0x00},
 {0xa5,0x00},
 {0xa6,0x00},
 {0xa7,0x00},
 {0xa8,0x00},
 {0xa9,0x00},
 {0xa1,0x80},
 {0xa2,0x80},

 //////////cc//////////////
 {0xfe , 0x02},
 {0xc0 , 0x01},
 {0xc1 , 0x40}, //Green_cc for d
 {0xc2 , 0xfc},
 {0xc3 , 0x05},
 {0xc4 , 0xec},
 {0xc5 , 0x42},
 {0xc6 , 0xf8},
 {0xc7 , 0x40},//for cwf
 {0xc8 , 0xf8},
 {0xc9 , 0x06},
 {0xca , 0xfd},
 {0xcb , 0x3e},
 {0xcc , 0xf3},
 {0xcd , 0x36},//for A
 {0xce , 0xf6},
 {0xcf , 0x04},
 {0xe3 , 0x0c},
 {0xe4 , 0x44},
 {0xe5 , 0xe5},
 {0xfe , 0x00},

 ///////awb start ////////////////
 //AWB clear
 {0xfe , 0x01},
 {0x4f , 0x00},
 {0x4d , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x10}, // 10
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x20}, // 20
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x30},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00}, // 30
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x40}, // 40
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x50}, // 50
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x60}, // 60
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x70}, // 70
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x80}, // 80
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0x90}, // 90
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xa0}, // a0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xb0}, // b0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xc0}, // c0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4d , 0xd0}, // d0
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4e , 0x00},
 {0x4f , 0x01},
 /////// awb value////////
 {0xfe , 0x01},
 {0x4f , 0x00},
 {0x4d , 0x30},
 {0x4e , 0x00},
 {0x4e , 0x80},
 {0x4e , 0x80},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4d , 0x40},
 {0x4e , 0x00},
 {0x4e , 0x80},
 {0x4e , 0x80},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4e , 0x02},
 {0x4d , 0x53},
 {0x4e , 0x08},
 {0x4e , 0x04},
 {0x4d , 0x62},
 {0x4e , 0x10},
 {0x4d , 0x72},
 {0x4e , 0x20},
 {0x4f , 0x01},

 /////awb////
 {0xfe , 0x01},
 {0x50 , 0x88},//c0//[6]green mode
 {0x52 , 0x40},
 {0x54 , 0x60},
 {0x56 , 0x06},
 {0x57 , 0x20}, //pre adjust
 {0x58 , 0x01},
 {0x5b , 0x02}, //AWB_gain_delta
 {0x61 , 0xaa},//R/G stand
 {0x62 , 0xaa},//R/G stand
 {0x71 , 0x00},
 {0x74 , 0x10},  //0x//AWB_C_max
 {0x77 , 0x08}, // 0x//AWB_p2_x
 {0x78 , 0xfd}, //AWB_p2_y
 {0x86 , 0x30},
 {0x87 , 0x00},
 {0x88 , 0x04},//06 , 0x//[1]dark mode
 {0x8a , 0xc0},//awb move mode
 {0x89 , 0x75},
 {0x84 , 0x08},  //0x//auto_window
 {0x8b , 0x00}, // 0x//awb compare luma
 {0x8d , 0x70}, //awb gain limit R
 {0x8e , 0x70},//G
 {0x8f , 0xf4},//B
 {0xfe , 0x00},
 {0x82 , 0x02},//awb_en
 /////////awb end /////////////

 ///==========asde
 {0xfe, 0x01},
 {0x21, 0xbf},
 {0xfe, 0x02},
 {0xa4, 0x00},//
 {0xa5, 0x40}, //lsc_th
 {0xa2, 0xa0}, //lsc_dec_slope
 {0x86, 0x27},//add for DPC travis 20140505
 {0x8a, 0x33},//add for DPC travis 20140505
 {0x8d, 0x85},//add for DPC travis 20140505
 {0xa6, 0xf0},//80//change for DPC travis 20140505
 {0xa7, 0x80}, //ot_th
 {0xab, 0x31}, //
 {0xa9, 0x6f}, //
 {0xb0, 0x99}, //0x//edge effect slope low
 {0xb1, 0x34},//edge effect slope low
 {0xb3, 0x80}, //saturation dec slope
 {0xde, 0xb6},  //
 {0x38, 0x0f}, //
 {0x39, 0x60}, //
 {0xfe, 0x00},
 {0x81, 0x26},
 {0xfe, 0x02},
 {0x83, 0x00},//
 {0x84, 0x45},//
 ////////////YCP//////////
 {0xd1 , 0x34},//saturation_cb
 {0xd2 , 0x34},//saturation_Cr
 {0xd3 , 0x40},//contrast ?	{0xd4 , 0x80},//contrast center
 {0xd4  , 0x80},//contrast center
 {0xd5 , 0x00},//luma_offset
 {0xdc , 0x30},
 {0xdd , 0xb8},//edge_sa_g,b
 {0xfe , 0x00},
 ///////dndd///////////
 {0xfe , 0x02},
 {0x88 , 0x15},//dn_b_base
 {0x8c , 0xf6}, //[2]b_in_dark_inc
 {0x89 , 0x03}, //dn_c_weight
 ////////EE ///////////
 {0xfe , 0x02},
 {0x90 , 0x6c},// EEINTP mode1
 {0x97 , 0x45},// edge effect
 ////==============RGB Gamma
 {0xfe , 0x02},
 {0x15 , 0x0a},
 {0x16 , 0x12},
 {0x17 , 0x19},
 {0x18 , 0x1f},
 {0x19 , 0x2c},
 {0x1a , 0x38},
 {0x1b , 0x42},
 {0x1c , 0x4e},
 {0x1d , 0x63},
 {0x1e , 0x76},
 {0x1f , 0x87},
 {0x20 , 0x96},
 {0x21 , 0xa2},
 {0x22 , 0xb8},
 {0x23 , 0xca},
 {0x24 , 0xd8},
 {0x25 , 0xe3},
 {0x26 , 0xf0},
 {0x27 , 0xf8},
 {0x28 , 0xfd},
 {0x29 , 0xff},

 ///=================y gamma
 {0xfe , 0x02},
 {0x2b , 0x00},
 {0x2c , 0x04},
 {0x2d , 0x09},
 {0x2e , 0x18},
 {0x2f , 0x27},
 {0x30 , 0x37},
 {0x31 , 0x49},
 {0x32 , 0x5c},
 {0x33 , 0x7e},
 {0x34 , 0xa0},
 {0x35 , 0xc0},
 {0x36 , 0xe0},
 {0x37 , 0xff},
 /////1600x1200size//
 {0xfe, 0x00},//
 {0x90, 0x01}, //0x//crop enable
 {0x94, 0x04},
 {0x95, 0x04},  //0x//1600x1200
 {0x96, 0xb0},
 {0x97, 0x06},
 {0x98, 0x40},

 {0xfe , 0x03},
 {0x40 , 0x40},  //00
 {0x41 , 0x02}, // Pclk_polarity
 {0x42 , 0x40},
 {0x43 , 0x06}, //output buf width
 {0x17 , 0x01}, //widv
 {0xfe , 0x00},

 ////output DVP/////
 {0xfe  , 0x00},
 {0x82  , 0xfe},  // fe
 {0xf2  , 0x70},
 {0xf3  , 0xff},
 {0xf4  , 0x00},
 {0xf5  , 0x30},

 #if 1
 /////////  re zao///
 {0xfe  , 0x00},
 {0x22  , 0xf0},
 {0xfe  , 0x01},
 {0x21  , 0xff},
 {0xfe  , 0x02},
 {0x8a  , 0x33},
 {0x8c  , 0x76},
 {0x8d  , 0x85},
 {0xa6  , 0xf0},
 {0xae  , 0x9f},
 {0xa2  , 0x90},
 {0xa5  , 0x40},
 {0xa7  , 0x30},
 {0xb0  , 0x88},
 {0x38  , 0x0b},
 {0x39  , 0x30},
 {0xfe  , 0x00},

 {0x87  , 0xb0},

 //// small  RGB gamma////
 /*
 {0xfe , 0x02},
 {0x15 , 0x0b},
 {0x16 , 0x0e},
 {0x17 , 0x10},
 {0x18 , 0x12},
 {0x19 , 0x19},
 {0x1a , 0x21},
 {0x1b , 0x29},
 {0x1c , 0x31},
 {0x1d , 0x41},
 {0x1e , 0x50},
 {0x1f , 0x5f},
 {0x20 , 0x6d},
 {0x21 , 0x79},
 {0x22 , 0x91},
 {0x23 , 0xa5},
 {0x24 , 0xb9},
 {0x25 , 0xc9},
 {0x26 , 0xe1},
 {0x27 , 0xee},
 {0x28 , 0xf7},
 {0x29 , 0xff},
 */
 ////dark sun/////
 {0xfe , 0x02},
 {0x40 , 0x06},
 {0x41 , 0x23},
 {0x42 , 0x3f},
 {0x43 , 0x06},
 {0x44 , 0x00},
 {0x45 , 0x00},
 {0x46 , 0x14},
 {0x47 , 0x09},
 {0xfe , 0x00},
 #endif

 };

 /* 1600X1200 UXGA 20fps */
 static struct regval_list sensor_uxga_regs_hres3[] =
 {
 {0xfe , 0x00},
 {0xb6,  0x03},
 {0xfa , 0x00},
 {0xc8 , 0x00},

 {0x99 , 0x11},// 1/2 subsample
 {0x9a , 0x06},
 {0x9b , 0x00},
 {0x9c , 0x00},
 {0x9d , 0x00},
 {0x9e , 0x00},
 {0x9f , 0x00},
 {0xa0 , 0x00},
 {0xa1 , 0x00},
 {0xa2 , 0x00},

 {0x90 , 0x01},
 {0x95 , 0x04},
 {0x96 , 0xb0},
 {0x97 , 0x06},
 {0x98 , 0x40},

 };

 /* 800X600 SVGA,20fps*/
 static struct regval_list sensor_svga_regs_hres3[] =
 {
 {0xfe,0x00},
 {0xb6,0x03},
 {0xfa,0x00},
 {0xc8,0x00},//close scaler

 {0x99,0x22},// 1/2 subsample
 {0x9a,0x07},
 {0x9b,0x00},
 {0x9c,0x00},
 {0x9d,0x00},
 {0x9e,0x00},
 {0x9f,0x00},
 {0xa0,0x00},
 {0xa1,0x00},
 {0xa2,0x00},

 {0x90,0x01},  //crop enable
 {0x95,0x02},
 {0x96,0x58},
 {0x97,0x03},
 {0x98,0x20},
 };

 /* 640x480 VGA,20fps*/
 static struct regval_list sensor_vga_regs_hres3[] =
 {
 {0xfe,0x00},
 {0xb6,0x03},
 {0xfa,0x00},
 {0xc8,0x02}, //close scaler

 {0x99,0x22},// 1/2 subsample
 {0x9a,0x06},
 {0x9b,0x00},
 {0x9c,0x00},
 {0x9d,0x00},
 {0x9e,0x00},
 {0x9f,0x00},
 {0xa0,0x00},
 {0xa1,0x00},
 {0xa2,0x00},

 {0x90,0x01},  //crop enable
 {0x95,0x02},
 {0x96,0x58},
 {0x97,0x03},
 {0x98,0x20},
 };

 /* 320x240 QVGA,20fps*/
 static struct regval_list sensor_qvga_regs_hres3[] =
 {
 {0xfe,0x00},
 {0xb6,0x03},
 {0xfa,0x00},
 {0xc8,0x02}, //close scaler

 {0x99,0x44},// 1/2 subsample
 {0x9a,0x06},
 {0x9b,0x00},
 {0x9c,0x00},
 {0x9d,0x00},
 {0x9e,0x00},
 {0x9f,0x00},
 {0xa0,0x00},
 {0xa1,0x00},
 {0xa2,0x00},

 {0x90,0x01},  //crop enable
 {0x95,0x02},
 {0x96,0x58},
 {0x97,0x03},
 {0x98,0x20},
 };


 static struct regval_list sensor_default_regs_hres2[] =
 {
 	{0xfe, 0x80},
 	{0xfe, 0x80},
 	{0xfe, 0x80},
 	{0xfc, 0x06},
 	{0xf2, 0x00},
 	{0xf3, 0x00},
 	{0xf4, 0x00},
 	{0xf5, 0x00},
 	{0xf9, 0xfe}, //[0] pll enable
 	{0xfa, 0x00},
 	{0xf6, 0x00},
 	{0xf7, 0x15}, //pll enable
     #if 1
 	{0xf8, 0x85},
 	#else
 	{0xf8, 0x84},
 	#endif
 	{0xfe, 0x00},
 	{0x82, 0x00},
 	{0xb3, 0x60},
 	{0xb4, 0x40},
 	{0xb5, 0x60},

 	#if 1
 	{0x03 , 0x02},
 	{0x04 , 0x80},
 	#else
 	{0x03, 0x04},
 	{0x04, 0x9b},
 	#endif
 	//////////measure window  ///////////
 	{0xfe, 0x00},
 	{0xec, 0x06},//04
 	{0xed, 0x06},//04
 	{0xee, 0x62},//60
 	{0xef, 0x92},//90

 	///////////analog/////////////
 	{0x0a, 0x00}, //row start
 	{0x0c, 0x00}, //col start
 	{0x0d, 0x04},
 	{0x0e, 0xc0},
 	{0x0f, 0x06}, //Window setting
 	{0x10, 0x58},
 	{0x17, 0x14}, //[0]mirror [1]flip


 	{0x18, 0x0e}, //sdark 4 row in even frame??
 	{0x19, 0x0c}, //AD pipe number

 	/*
 	///  Ã«´Ì ÏÖÏó
 	{0x18,0x0a}, //sdark 4 row in even frame??
 	{0x19,0x0a}, //AD pipe number
 	*/

 	{0x1a , 0x01}, //CISCTL mode4
 	{0x1b , 0x8b},
 	{0x1c , 0x05},
 	{0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias
 	{0x1f , 0x08}, //[3] tx-low en//
 	{0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en
 	{0x21 , 0x0f}, //[6:4]rsg
 	{0x22 , 0xf0}, //[3:0]vref
 	{0x23 , 0xc3}, //f3//ADC_r
 	{0x24 , 0x17}, //pad drive  16

 	//AEC
 	{0xfe, 0x01},
 	{0x11, 0x20},//AEC_out_slope , 0x
 	{0x1f, 0xc0},//max_post_gain
 	{0x20, 0x60},//max_pre_gain
 	{0x47, 0x30},//AEC_outdoor_th
 	{0x0b, 0x10},//
 	{0x13, 0x75},//y_target
 	{0xfe, 0x00},

 #if 0
 	{0x05 , 0x01},//hb
 	{0x06 , 0x11},
 	{0x07 , 0x00},//vb
 	{0x08 , 0x50},
 	{0xfe , 0x01},
 	{0x27 , 0x00},//step
 	{0x28 , 0xa0},
 	{0x29 , 0x05},//level1
 	{0x2a , 0x00},
 	{0x2b , 0x05},//level2
 	{0x2c , 0x00},
 	{0x2d , 0x06},//6e8//level3
 	{0x2e , 0xe0},
 	{0x2f , 0x0a},//level4
 	{0x30 , 0x00},
 	{0x3e , 0x40},
 #else
 	{0xfe , 0x00},
 	{0x05 , 0x01},
 	{0x06 , 0x0d},
 	{0x07 , 0x00},
 	{0x08 , 0x40},
 	{0xfe , 0x01},
 	{0x27 , 0x00},
 	{0x28 , 0xa0},
 	{0x29 , 0x05},//  level 0 12.5
 	{0x2a , 0x00},
 	{0x2b , 0x05},//  level 1 12.5
 	{0x2c , 0x00},
 	{0x2d , 0x05},//  level 2 12.5 640/10fps
 	{0x2e , 0x00},
 	{0x2f , 0x08},//  level 3 7.5
 	{0x30 , 0x20},
 #endif

 	{0xfe , 0x00},
 	{0xfe , 0x00},  //0x , 0x , 0x , 0x , 0x
 	{0xb6 , 0x03}, //AEC enable
 	{0xfe , 0x00},

 	/////////BLK//////
 	{0x3f, 0x00}, //prc close
 	{0x40, 0x77},//
 	{0x42, 0x7f},
 	{0x43, 0x30},
 	{0x5c, 0x08},
 	{0x5e, 0x20},
 	{0x5f, 0x20},
 	{0x60, 0x20},
 	{0x61, 0x20},
 	{0x62, 0x20},
 	{0x63, 0x20},
 	{0x64, 0x20},
 	{0x65, 0x20},

 	///block////////////
 	{0x80, 0xff},
 	{0x81, 0x26},//38 , 0x//skin_Y 8c_debug
 	{0x87, 0x90}, //[7]middle gamma
 	{0x84, 0x03}, //output put foramat
 	{0x86, 0x07}, ////sync plority  02 86
 	{0x8b, 0xbc},
 	{0xb0, 0x80}, //globle gain
 	{0xc0, 0x40},//Yuv bypass

 	//////lsc/////////////
 #if 0
 	{0xfe, 0x01},
 	{0xc2, 0x38},
 	{0xc3, 0x25},
 	{0xc4, 0x21},
 	{0xc8, 0x19},
 	{0xc9, 0x12},
 	{0xca, 0x0e},
 	{0xbc, 0x28},// left R 0x43
 	{0xbd, 0x18},//0x18
 	{0xbe, 0x1b},//0x1b
 	{0xb6, 0x40},//right  0x40
 	{0xb7, 0x2e},
 	{0xb8, 0x26},
 	{0xc5, 0x05},
 	{0xc6, 0x03},
 	{0xc7, 0x04},
 	{0xcb, 0x00},
 	{0xcc, 0x00},
 	{0xcd, 0x00},
 	{0xbf, 0x14},
 	{0xc0, 0x22},
 	{0xc1, 0x1b},
 	{0xb9, 0x00},
 	{0xba, 0x05},
 	{0xbb, 0x05},
 	{0xaa, 0x35},
 	{0xab, 0x33},
 	{0xac, 0x33},
 	{0xad, 0x25},
 	{0xae, 0x22},
 	{0xaf, 0x27},
 	{0xb0, 0x1d},
 	{0xb1, 0x20},
 	{0xb2, 0x22},
 	{0xb3, 0x14},
 	{0xb4, 0x15},
 	{0xb5, 0x16},
 	{0xd0, 0x00},
 	{0xd2, 0x07},
 	{0xd3, 0x08},
 	{0xd8, 0x00},
 	{0xda, 0x13},
 	{0xdb, 0x17},
 	{0xdc, 0x00},
 	{0xde, 0x0a},
 	{0xdf, 0x08},
 	{0xd4, 0x00},
 	{0xd6, 0x00},
 	{0xd7, 0x0c},
 	{0xa4, 0x00},
 	{0xa5, 0x00},
 	{0xa6, 0x00},
 	{0xa7, 0x00},
 	{0xa8, 0x00},
 	{0xa9, 0x00},
 	{0xa1, 0x80},
 	{0xa2, 0x80},
 #else
 	//gc2035 Alight lsc reg setting list
 	////Record date: 2013-11-29 13:30:15

 	{0xfe,0x01},
 	{0xc2,0x21},
 	{0xc3,0x1a},
 	{0xc4,0x13},
 	{0xc8,0x17},
 	{0xc9,0x0f},
 	{0xca,0x00},
 	{0xbc,0x36},
 	{0xbd,0x2b},
 	{0xbe,0x17},
 	{0xb6,0x39},
 	{0xb7,0x21},
 	{0xb8,0x1c},
 	{0xc5,0x00},
 	{0xc6,0x00},
 	{0xc7,0x00},
 	{0xcb,0x00},
 	{0xcc,0x0c},
 	{0xcd,0x15},
 	{0xbf,0x00},
 	{0xc0,0x00},
 	{0xc1,0x00},
 	{0xb9,0x00},
 	{0xba,0x00},
 	{0xbb,0x00},
 	{0xaa,0x15},
 	{0xab,0x15},
 	{0xac,0x15},
 	{0xad,0x14},
 	{0xae,0x13},
 	{0xaf,0x12},
 	{0xb0,0x1b},
 	{0xb1,0x14},
 	{0xb2,0x14},
 	{0xb3,0x1f},
 	{0xb4,0x12},
 	{0xb5,0x13},
 	{0xd0,0x00},
 	{0xd2,0x00},
 	{0xd3,0x0c},
 	{0xd8,0x00},
 	{0xda,0x00},
 	{0xdb,0x13},
 	{0xdc,0x00},
 	{0xde,0x00},
 	{0xdf,0x25},
 	{0xd4,0x00},
 	{0xd6,0x00},
 	{0xd7,0x12},
 	{0xa4,0x00},
 	{0xa5,0x00},
 	{0xa6,0x00},
 	{0xa7,0x00},
 	{0xa8,0x00},
 	{0xa9,0x00},
 	{0xa1,0x80},
 	{0xa2,0x80},
 #endif

 	//////////cc//////////////
 	{0xfe, 0x02},
 	{0xc0, 0x01},
 	{0xc1, 0x40}, //Green_cc for d
 	{0xc2, 0xfc},
 	{0xc3, 0x05},
 	{0xc4, 0xec},
 	{0xc5, 0x42},
 	{0xc6, 0xf8},
 	{0xc7, 0x40},//for cwf
 	{0xc8, 0xf8},
 	{0xc9, 0x06},
 	{0xca, 0xfd},
 	{0xcb, 0x3e},
 	{0xcc, 0xf3},
 	{0xcd, 0x36},//for A
 	{0xce, 0xf6},
 	{0xcf, 0x04},
 	{0xe3, 0x0c},
 	{0xe4, 0x44},
 	{0xe5, 0xe5},
 	{0xfe, 0x00},

 	///////awb start ////////////////
 	//AWB clear
 	{0xfe, 0x01},
 	{0x4f, 0x00},
 	{0x4d, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x10}, // 10
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x20}, // 20
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x30},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00}, // 30
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x40}, // 40
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x50}, // 50
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x60}, // 60
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x70}, // 70
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x80}, // 80
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0x90}, // 90
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0xa0}, // a0
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0xb0}, // b0
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0xc0}, // c0
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4d, 0xd0}, // d0
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4e, 0x00},
 	{0x4f, 0x01},
 	/////// awb value////////
 	{0xfe, 0x01},
 	{0x4f, 0x00},
 	{0x4d, 0x30},
 	{0x4e, 0x00},
 	{0x4e, 0x80},
 	{0x4e, 0x80},
 	{0x4e, 0x02},
 	{0x4e, 0x02},
 	{0x4d, 0x40},
 	{0x4e, 0x00},
 	{0x4e, 0x80},
 	{0x4e, 0x80},
 	{0x4e, 0x02},
 	{0x4e, 0x02},
 	{0x4e, 0x02},
 	{0x4d, 0x53},
 	{0x4e, 0x08},
 	{0x4e, 0x04},
 	{0x4d, 0x62},
 	{0x4e, 0x10},
 	{0x4d, 0x72},
 	{0x4e, 0x20},
 	{0x4f, 0x01},

 	/////awb////
 	{0xfe, 0x01},
 	{0x50, 0x88},//c0//[6]green mode
 	{0x52, 0x40},
 	{0x54, 0x60},
 	{0x56, 0x06},
 	{0x57, 0x20}, //pre adjust
 	{0x58, 0x01},
 	{0x5b, 0x02}, //AWB_gain_delta
 	{0x61, 0xaa},//R/G stand
 	{0x62, 0xaa},//R/G stand
 	{0x71, 0x00},
 	{0x74, 0x10},  //0x//AWB_C_max
 	{0x77, 0x08}, // 0x//AWB_p2_x
 	{0x78, 0xfd}, //AWB_p2_y
 	{0x86, 0x30},
 	{0x87, 0x00},
 	{0x88, 0x04},//06 , 0x//[1]dark mode
 	{0x8a, 0xc0},//awb move mode
 	{0x89, 0x75},
 	{0x84, 0x08},  //0x//auto_window
 	{0x8b, 0x00}, // 0x//awb compare luma
 	{0x8d, 0x70}, //awb gain limit R
 	{0x8e, 0x70},//G
 	{0x8f, 0xf4},//B
 	{0xfe, 0x00},
 	{0x82, 0x02},//awb_en
     /////////awb end /////////////

 	///==========asde
 	{0xfe, 0x01},
 	{0x21, 0xbf},
 	{0xfe, 0x02},
 	{0xa4, 0x00},//
 	{0xa5, 0x40}, //lsc_th
 	{0xa2, 0xa0}, //lsc_dec_slope
 	{0x86, 0x27},//add for DPC travis 20140505
 	{0x8a, 0x33},//add for DPC travis 20140505
 	{0x8d, 0x85},//add for DPC travis 20140505
 	{0xa6, 0xf0},//80//change for DPC travis 20140505
 	{0xa7, 0x80}, //ot_th
 	{0xab, 0x31}, //
 	{0xa9, 0x6f}, //
 	{0xb0, 0x99}, //0x//edge effect slope low
 	{0xb1, 0x34},//edge effect slope low
 	{0xb3, 0x80}, //saturation dec slope
 	{0xde, 0xb6},  //
 	{0x38, 0x0f}, //
 	{0x39, 0x60}, //
 	{0xfe, 0x00},
 	{0x81, 0x26},
 	{0xfe, 0x02},
 	{0x83, 0x00},//
 	{0x84, 0x45},//
 	////////////YCP//////////
 	{0xd1, 0x38},//saturation_cb
 	{0xd2, 0x38},//saturation_Cr
 	{0xd3, 0x40},//contrast ?
 	{0xd4, 0x80},//contrast center
 	{0xd5, 0x00},//luma_offset
 	{0xdc, 0x30},
 	{0xdd, 0xb8},  //edge_sa_g,b
 	{0xfe, 0x00},
 	///////dndd///////////
 	{0xfe, 0x02},
 	{0x88, 0x15},//dn_b_base
 	{0x8c, 0xf6}, //[2]b_in_dark_inc
 	{0x89, 0x03}, //dn_c_weight
 	////////EE ///////////
 	{0xfe, 0x02},
 	{0x90, 0x6c},// EEINTP mode1
 	{0x97, 0x45},// edge effect
 	////==============RGB Gamma
 	{0xfe, 0x02},
 	{0x15, 0x0a},
 	{0x16, 0x12},
 	{0x17, 0x19},
 	{0x18, 0x1f},
 	{0x19, 0x2c},
 	{0x1a, 0x38},
 	{0x1b, 0x42},
 	{0x1c, 0x4e},
 	{0x1d, 0x63},
 	{0x1e, 0x76},
 	{0x1f, 0x87},
 	{0x20, 0x96},
 	{0x21, 0xa2},
 	{0x22, 0xb8},
 	{0x23, 0xca},
 	{0x24, 0xd8},
 	{0x25, 0xe3},
 	{0x26, 0xf0},
 	{0x27, 0xf8},
 	{0x28, 0xfd},
 	{0x29, 0xff},

 	///=================y gamma
 	{0xfe, 0x02},
 	{0x2b, 0x00},
 	{0x2c, 0x04},
 	{0x2d, 0x09},
 	{0x2e, 0x18},
 	{0x2f, 0x27},
 	{0x30, 0x37},
 	{0x31, 0x49},
 	{0x32, 0x5c},
 	{0x33, 0x7e},
 	{0x34, 0xa0},
 	{0x35, 0xc0},
 	{0x36, 0xe0},
 	{0x37, 0xff},
 	/////1600x1200size//
 	{0xfe, 0x00},//
 	{0x90, 0x01}, //0x//crop enable
 	{0x95, 0x04},  //0x//1600x1200
 	{0x96, 0xb0},
 	{0x97, 0x06},
 	{0x98, 0x40},

 	{0xfe, 0x03},
 	{0x42, 0x40},
 	{0x43, 0x06}, //output buf width
 	{0x41, 0x02}, // Pclk_polarity
 	{0x40, 0x40},  //00
 	{0x17, 0x00}, //widv
 	{0xfe, 0x00},
 	////output DVP/////
 	{0xfe , 0x00},
 	{0xb6 , 0x03},
 	{0xfa , 0x00},

 	{0xc8, 0x00},//close scaler
 	{0x99, 0x22},// 1/2 subsample
 	{0x9a, 0x06},
 	{0x9b, 0x00},
 	{0x9c, 0x00},
 	{0x9d, 0x00},
 	{0x9e, 0x00},
 	{0x9f, 0x00},
 	{0xa0, 0x00},
 	{0xa1, 0x00},
 	{0xa2, 0x00},

 	{0x90, 0x01},  //crop enable
 	{0x94, 0x02},
 	{0x95, 0x02},
 	{0x96, 0x5a},
 	{0x97, 0x03},
 	{0x98, 0x20},
 	{0xfe, 0x00},
 	{0x82, 0xfe},  // fe
 	{0xf2, 0x70},
 	{0xf3, 0xff},
 	{0xf4, 0x00},
 	{0xf5, 0x30},

 #if 0
     /////////  re zao///
 	{0xfe,0x00},
 	{0x22,0xf0},
 	{0xfe,0x01},
 	{0x21,0xff},
 	{0xfe,0x02},
 	{0x8a,0x33},
 	{0x8c,0x76},
 	{0x8d,0x85},
 	{0xa6,0xf0},
 	{0xae,0x9f},
 	{0xa2,0x90},
 	{0xa5,0x40},
 	{0xa7,0x30},
 	{0xb0,0x88},
 	{0x38,0x0b},
 	{0x39,0x30},
 	{0xfe,0x00},
 	{0x87,0xb0},

        //// small  RGB gamma////
 	{0xfe, 0x02},
 	{0x15, 0x0b},
 	{0x16, 0x0e},
 	{0x17, 0x10},
 	{0x18, 0x12},
 	{0x19, 0x19},
 	{0x1a, 0x21},
 	{0x1b, 0x29},
 	{0x1c, 0x31},
 	{0x1d, 0x41},
 	{0x1e, 0x50},
 	{0x1f, 0x5f},
 	{0x20, 0x6d},
 	{0x21, 0x79},
 	{0x22, 0x91},
 	{0x23, 0xa5},
 	{0x24, 0xb9},
 	{0x25, 0xc9},
 	{0x26, 0xe1},
 	{0x27, 0xee},
 	{0x28, 0xf7},
 	{0x29, 0xff},

  	////dark sun/////
 	{0xfe, 0x02},
 	{0x40, 0x06},
 	{0x41, 0x23},
 	{0x42, 0x3f},
 	{0x43, 0x06},
 	{0x44, 0x00},
 	{0x45, 0x00},
 	{0x46, 0x14},
 	{0x47, 0x09},
 #endif
 #ifdef Auto_LSC_debug
   {0xfe , 0x00},
   {0x80 , 0x08},
   {0x81 , 0x00},
   {0x82 , 0x00},
   {0xa3 , 0x80},
   {0xa4 , 0x80},
   {0xa5 , 0x80},
   {0xa6 , 0x80},
   {0xa7 , 0x80},
   {0xa8 , 0x80},
   {0xa9 , 0x80},
   {0xaa , 0x80},
   {0xad , 0x80},
   {0xae , 0x80},
   {0xaf , 0x80},
   {0xb3 , 0x40},
   {0xb4 , 0x40},
   {0xb5 , 0x40},
   {0xfe , 0x01},
   {0x0a , 0x40},
   {0x13 , 0x48},
   {0x9f , 0x40},
   {0xfe , 0x02},
   {0xd0 , 0x40},
   {0xd1 , 0x20},
   {0xd2 , 0x20},
   {0xd3 , 0x40},
   {0xd5 , 0x00},
   {0xdd , 0x00},
   {0xfe , 0x00},
 #endif
 };

/* 640x480 VGA,15fps*/
static struct regval_list sensor_vga_regs_hres2[] ={};

/* 352x288 CIF,15fps*/
static struct regval_list sensor_cif_regs_hres2[] = {};

/* 320x240 QVGA,15fps*/
static struct regval_list sensor_qvga_regs_hres2[] = {};

static struct sensor_win_size
sensor_win_sizes_hres0[] =
{
  /* UXGA */
  {
    .width      = UXGA_WIDTH,
    .height     = UXGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_uxga_regs_hres0,
    .regs_size  = ARRAY_SIZE(sensor_uxga_regs_hres0),
    .set_size   = NULL,
  },
  /* 720p */
  {
    .width      = HD720_WIDTH,
    .height     = HD720_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
		.regs		= Gc2015_sensor_hd720_regs_hres0,
		.regs_size	= ARRAY_SIZE(Gc2015_sensor_hd720_regs_hres0),
    .set_size   = NULL,
  },
  /* VGA */
  {
    .width      = VGA_WIDTH,
    .height     = VGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_vga_regs_hres0,
    .regs_size  = ARRAY_SIZE(sensor_vga_regs_hres0),
    .set_size   = NULL,
  },
};

static struct sensor_win_size
sensor_win_sizes_hres1[] =
{
  /* UXGA */
  {
    .width      = UXGA_WIDTH,
    .height     = UXGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_uxga_regs_hres1,
    .regs_size  = ARRAY_SIZE(sensor_uxga_regs_hres1),
    .set_size   = NULL,
  },
  /* SVGA */
  {
    .width      = SVGA_WIDTH,
    .height     = SVGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_svga_regs_hres1,
    .regs_size  = ARRAY_SIZE(sensor_svga_regs_hres1),
    .set_size   = NULL,
  },
};

static struct sensor_win_size
sensor_win_sizes_hres2[] =
{
  /* VGA */
  {
    .width      = VGA_WIDTH,
    .height     = VGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_vga_regs_hres2,
    .regs_size  = ARRAY_SIZE(sensor_vga_regs_hres2),
    .set_size   = NULL,
  },
  /* CIF */
  {
    .width      = CIF_WIDTH,
    .height     = CIF_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_cif_regs_hres2,
    .regs_size  = ARRAY_SIZE(sensor_qvga_regs_hres2),
    .set_size   = NULL,
  },
  /* QVGA */
  {
    .width      = QVGA_WIDTH,
    .height     = QVGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_qvga_regs_hres2,
    .regs_size  = ARRAY_SIZE(sensor_qvga_regs_hres2),
    .set_size   = NULL,
  },
};

static struct sensor_win_size
sensor_win_sizes_hres3[] =
{
  /* UXGA */
  {
    .width      = UXGA_WIDTH,
    .height     = UXGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_uxga_regs_hres3,
    .regs_size  = ARRAY_SIZE(sensor_uxga_regs_hres3),
    .set_size   = NULL,
  },
  /* SVGA */
  {
    .width      = SVGA_WIDTH,
    .height     = SVGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_svga_regs_hres3,
    .regs_size  = ARRAY_SIZE(sensor_svga_regs_hres3),
    .set_size   = NULL,
  },
  /* VGA */
  {
    .width      = VGA_WIDTH,
    .height     = VGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_vga_regs_hres3,
    .regs_size  = ARRAY_SIZE(sensor_vga_regs_hres3),
    .set_size   = NULL,
  },
  /* QVGA */
  {
    .width      = QVGA_WIDTH,
    .height     = QVGA_HEIGHT,
    .hoffset    = 0,
    .voffset    = 0,
    .regs       = sensor_qvga_regs_hres3,
    .regs_size  = ARRAY_SIZE(sensor_qvga_regs_hres3),
    .set_size   = NULL,
  },
};

/*
 * The white balance settings
 * Here only tune the R G B channel gain.
 * The white balance enalbe bit is modified in sensor_s_autowb and sensor_s_wb
 */
static struct regval_list sensor_wb_manual[] = {};

static struct regval_list sensor_wb_auto_regs[] =
{
	{0x82, 0xfe},
	{0xb3, 0x61},
	{0xb4, 0x40},
	{0xb5, 0x61},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_incandescence_regs[] =
{
	//bai re guang
	{0x82, 0xfd},
	{0xb3, 0x50},
	{0xb4, 0x40},
	{0xb5, 0xa8},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_fluorescent_regs[] =
{
	//ri guang deng
	{0x82, 0xfd},
	{0xb3, 0x72},
	{0xb4, 0x40},
	{0xb5, 0x5b},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_tungsten_regs[] =
{
	//wu si deng
	{0x82, 0xfd},
	{0xb3, 0xa0},
	{0xb4, 0x45},
	{0xb5, 0x40},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_horizon[] = {};

static struct regval_list sensor_wb_daylight_regs[] =
{
	//tai yang guang
	//Sunny
	{0x82, 0xfd},
	{0xb3, 0x58},
	{0xb4, 0x40},
	{0xb5, 0x50},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_flash[] = {};

static struct regval_list sensor_wb_cloud_regs[] =
{
	{0x82, 0xfd},
	{0xb3, 0x58},
	{0xb4, 0x40},
	{0xb5, 0x50},
	{0xff, 0xff},
};

static struct regval_list sensor_wb_shade[] = {};

static struct cfg_array sensor_wb[] =
{
  {
  	.regs = sensor_wb_manual,             //V4L2_WHITE_BALANCE_MANUAL
    .size = ARRAY_SIZE(sensor_wb_manual),
  },
  {
  	.regs = sensor_wb_auto_regs,          //V4L2_WHITE_BALANCE_AUTO
    .size = ARRAY_SIZE(sensor_wb_auto_regs),
  },
  {
  	.regs = sensor_wb_incandescence_regs, //V4L2_WHITE_BALANCE_INCANDESCENT
    .size = ARRAY_SIZE(sensor_wb_incandescence_regs),
  },
  {
  	.regs = sensor_wb_fluorescent_regs,   //V4L2_WHITE_BALANCE_FLUORESCENT
    .size = ARRAY_SIZE(sensor_wb_fluorescent_regs),
  },
  {
  	.regs = sensor_wb_tungsten_regs,      //V4L2_WHITE_BALANCE_FLUORESCENT_H
    .size = ARRAY_SIZE(sensor_wb_tungsten_regs),
  },
  {
  	.regs = sensor_wb_horizon,            //V4L2_WHITE_BALANCE_HORIZON
    .size = ARRAY_SIZE(sensor_wb_horizon),
  },
  {
  	.regs = sensor_wb_daylight_regs,      //V4L2_WHITE_BALANCE_DAYLIGHT
    .size = ARRAY_SIZE(sensor_wb_daylight_regs),
  },
  {
  	.regs = sensor_wb_flash,              //V4L2_WHITE_BALANCE_FLASH
    .size = ARRAY_SIZE(sensor_wb_flash),
  },
  {
  	.regs = sensor_wb_cloud_regs,         //V4L2_WHITE_BALANCE_CLOUDY
    .size = ARRAY_SIZE(sensor_wb_cloud_regs),
  },
  {
  	.regs = sensor_wb_shade,              //V4L2_WHITE_BALANCE_SHADE
    .size = ARRAY_SIZE(sensor_wb_shade),
  },
//  {
//  	.regs = NULL,
//    .size = 0,
//  },
};


/*
 * The color effect settings
 */
static struct regval_list sensor_colorfx_none_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0xe0},
};

static struct regval_list sensor_colorfx_bw_regs[] = {};

static struct regval_list sensor_colorfx_sepia_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0x82},
};

static struct regval_list sensor_colorfx_negative_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0x01},
};

static struct regval_list sensor_colorfx_emboss_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0x12},///CAM_EFFECT_ENC_GRAYSCALE
};

static struct regval_list sensor_colorfx_sketch_regs[] = {};

static struct regval_list sensor_colorfx_sky_blue_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0x62},
};

static struct regval_list sensor_colorfx_grass_green_regs[] =
{
	{0xfe, 0x00},
	{0x83, 0x52},
};

static struct regval_list sensor_colorfx_skin_whiten_regs[] = {};

static struct regval_list sensor_colorfx_vivid_regs[] = {};

static struct regval_list sensor_colorfx_aqua_regs[] = {};

static struct regval_list sensor_colorfx_art_freeze_regs[] = {};

static struct regval_list sensor_colorfx_silhouette_regs[] = {};

static struct regval_list sensor_colorfx_solarization_regs[] = {};

static struct regval_list sensor_colorfx_antique_regs[] = {};

static struct regval_list sensor_colorfx_set_cbcr_regs[] = {};

static struct cfg_array sensor_colorfx[] =
{
  {
  	.regs = sensor_colorfx_none_regs,         //V4L2_COLORFX_NONE = 0,
    .size = ARRAY_SIZE(sensor_colorfx_none_regs),
  },
  {
  	.regs = sensor_colorfx_bw_regs,           //V4L2_COLORFX_BW   = 1,
    .size = ARRAY_SIZE(sensor_colorfx_bw_regs),
  },
  {
  	.regs = sensor_colorfx_sepia_regs,        //V4L2_COLORFX_SEPIA  = 2,
    .size = ARRAY_SIZE(sensor_colorfx_sepia_regs),
  },
  {
  	.regs = sensor_colorfx_negative_regs,     //V4L2_COLORFX_NEGATIVE = 3,
    .size = ARRAY_SIZE(sensor_colorfx_negative_regs),
  },
  {
  	.regs = sensor_colorfx_emboss_regs,       //V4L2_COLORFX_EMBOSS = 4,
    .size = ARRAY_SIZE(sensor_colorfx_emboss_regs),
  },
  {
  	.regs = sensor_colorfx_sketch_regs,       //V4L2_COLORFX_SKETCH = 5,
    .size = ARRAY_SIZE(sensor_colorfx_sketch_regs),
  },
  {
  	.regs = sensor_colorfx_sky_blue_regs,     //V4L2_COLORFX_SKY_BLUE = 6,
    .size = ARRAY_SIZE(sensor_colorfx_sky_blue_regs),
  },
  {
  	.regs = sensor_colorfx_grass_green_regs,  //V4L2_COLORFX_GRASS_GREEN = 7,
    .size = ARRAY_SIZE(sensor_colorfx_grass_green_regs),
  },
  {
  	.regs = sensor_colorfx_skin_whiten_regs,  //V4L2_COLORFX_SKIN_WHITEN = 8,
    .size = ARRAY_SIZE(sensor_colorfx_skin_whiten_regs),
  },
  {
  	.regs = sensor_colorfx_vivid_regs,        //V4L2_COLORFX_VIVID = 9,
    .size = ARRAY_SIZE(sensor_colorfx_vivid_regs),
  },
  {
  	.regs = sensor_colorfx_aqua_regs,         //V4L2_COLORFX_AQUA = 10,
    .size = ARRAY_SIZE(sensor_colorfx_aqua_regs),
  },
  {
  	.regs = sensor_colorfx_art_freeze_regs,   //V4L2_COLORFX_ART_FREEZE = 11,
    .size = ARRAY_SIZE(sensor_colorfx_art_freeze_regs),
  },
  {
  	.regs = sensor_colorfx_silhouette_regs,   //V4L2_COLORFX_SILHOUETTE = 12,
    .size = ARRAY_SIZE(sensor_colorfx_silhouette_regs),
  },
  {
  	.regs = sensor_colorfx_solarization_regs, //V4L2_COLORFX_SOLARIZATION = 13,
    .size = ARRAY_SIZE(sensor_colorfx_solarization_regs),
  },
  {
  	.regs = sensor_colorfx_antique_regs,      //V4L2_COLORFX_ANTIQUE = 14,
    .size = ARRAY_SIZE(sensor_colorfx_antique_regs),
  },
  {
  	.regs = sensor_colorfx_set_cbcr_regs,     //V4L2_COLORFX_SET_CBCR = 15,
    .size = ARRAY_SIZE(sensor_colorfx_set_cbcr_regs),
  },
};

/*
 * The brightness setttings
 */
static struct regval_list sensor_brightness_neg4_regs[] = {};

static struct regval_list sensor_brightness_neg3_regs[] = {};

static struct regval_list sensor_brightness_neg2_regs[] = {};

static struct regval_list sensor_brightness_neg1_regs[] = {};

static struct regval_list sensor_brightness_zero_regs[] = {};

static struct regval_list sensor_brightness_pos1_regs[] = {};

static struct regval_list sensor_brightness_pos2_regs[] = {};

static struct regval_list sensor_brightness_pos3_regs[] = {};

static struct regval_list sensor_brightness_pos4_regs[] = {};

static struct cfg_array sensor_brightness[] =
{
  {
  	.regs = sensor_brightness_neg4_regs,
  	.size = ARRAY_SIZE(sensor_brightness_neg4_regs),
  },
  {
  	.regs = sensor_brightness_neg3_regs,
  	.size = ARRAY_SIZE(sensor_brightness_neg3_regs),
  },
  {
  	.regs = sensor_brightness_neg2_regs,
  	.size = ARRAY_SIZE(sensor_brightness_neg2_regs),
  },
  {
  	.regs = sensor_brightness_neg1_regs,
  	.size = ARRAY_SIZE(sensor_brightness_neg1_regs),
  },
  {
  	.regs = sensor_brightness_zero_regs,
  	.size = ARRAY_SIZE(sensor_brightness_zero_regs),
  },
  {
  	.regs = sensor_brightness_pos1_regs,
  	.size = ARRAY_SIZE(sensor_brightness_pos1_regs),
  },
  {
  	.regs = sensor_brightness_pos2_regs,
  	.size = ARRAY_SIZE(sensor_brightness_pos2_regs),
  },
  {
  	.regs = sensor_brightness_pos3_regs,
  	.size = ARRAY_SIZE(sensor_brightness_pos3_regs),
  },
  {
  	.regs = sensor_brightness_pos4_regs,
  	.size = ARRAY_SIZE(sensor_brightness_pos4_regs),
  },
};

/*
 * The contrast setttings
 */
static struct regval_list sensor_contrast_neg4_regs[] = {};

static struct regval_list sensor_contrast_neg3_regs[] = {};

static struct regval_list sensor_contrast_neg2_regs[] = {};

static struct regval_list sensor_contrast_neg1_regs[] = {};

static struct regval_list sensor_contrast_zero_regs[] = {};

static struct regval_list sensor_contrast_pos1_regs[] = {};

static struct regval_list sensor_contrast_pos2_regs[] = {};

static struct regval_list sensor_contrast_pos3_regs[] = {};

static struct regval_list sensor_contrast_pos4_regs[] = {};

static struct cfg_array sensor_contrast[] =
{
  {
  	.regs = sensor_contrast_neg4_regs,
  	.size = ARRAY_SIZE(sensor_contrast_neg4_regs),
  },
  {
  	.regs = sensor_contrast_neg3_regs,
  	.size = ARRAY_SIZE(sensor_contrast_neg3_regs),
  },
  {
  	.regs = sensor_contrast_neg2_regs,
  	.size = ARRAY_SIZE(sensor_contrast_neg2_regs),
  },
  {
  	.regs = sensor_contrast_neg1_regs,
  	.size = ARRAY_SIZE(sensor_contrast_neg1_regs),
  },
  {
  	.regs = sensor_contrast_zero_regs,
  	.size = ARRAY_SIZE(sensor_contrast_zero_regs),
  },
  {
  	.regs = sensor_contrast_pos1_regs,
  	.size = ARRAY_SIZE(sensor_contrast_pos1_regs),
  },
  {
  	.regs = sensor_contrast_pos2_regs,
  	.size = ARRAY_SIZE(sensor_contrast_pos2_regs),
  },
  {
  	.regs = sensor_contrast_pos3_regs,
  	.size = ARRAY_SIZE(sensor_contrast_pos3_regs),
  },
  {
  	.regs = sensor_contrast_pos4_regs,
  	.size = ARRAY_SIZE(sensor_contrast_pos4_regs),
  },
};

/*
 * The saturation setttings
 */
static struct regval_list sensor_saturation_neg4_regs[] = {};

static struct regval_list sensor_saturation_neg3_regs[] = {};

static struct regval_list sensor_saturation_neg2_regs[] = {};

static struct regval_list sensor_saturation_neg1_regs[] = {};

static struct regval_list sensor_saturation_zero_regs[] = {};

static struct regval_list sensor_saturation_pos1_regs[] = {};

static struct regval_list sensor_saturation_pos2_regs[] = {};

static struct regval_list sensor_saturation_pos3_regs[] = {};

static struct regval_list sensor_saturation_pos4_regs[] = {};

static struct cfg_array sensor_saturation[] =
{
  {
  	.regs = sensor_saturation_neg4_regs,
  	.size = ARRAY_SIZE(sensor_saturation_neg4_regs),
  },
  {
  	.regs = sensor_saturation_neg3_regs,
  	.size = ARRAY_SIZE(sensor_saturation_neg3_regs),
  },
  {
  	.regs = sensor_saturation_neg2_regs,
  	.size = ARRAY_SIZE(sensor_saturation_neg2_regs),
  },
  {
  	.regs = sensor_saturation_neg1_regs,
  	.size = ARRAY_SIZE(sensor_saturation_neg1_regs),
  },
  {
  	.regs = sensor_saturation_zero_regs,
  	.size = ARRAY_SIZE(sensor_saturation_zero_regs),
  },
  {
  	.regs = sensor_saturation_pos1_regs,
  	.size = ARRAY_SIZE(sensor_saturation_pos1_regs),
  },
  {
  	.regs = sensor_saturation_pos2_regs,
  	.size = ARRAY_SIZE(sensor_saturation_pos2_regs),
  },
  {
  	.regs = sensor_saturation_pos3_regs,
  	.size = ARRAY_SIZE(sensor_saturation_pos3_regs),
  },
  {
  	.regs = sensor_saturation_pos4_regs,
  	.size = ARRAY_SIZE(sensor_saturation_pos4_regs),
  },
};

/*
 * The exposure target setttings
 */
static struct regval_list sensor_ev_neg4_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x40},
	{0xfe, 0x02},
	{0xd5, 0xc0},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_neg3_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x50},
	{0xfe, 0x02},
	{0xd5, 0xd0},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_neg2_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x60},
	{0xfe, 0x02},
	{0xd5, 0xe0},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_neg1_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x70},
	{0xfe, 0x02},
	{0xd5, 0xf0},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_zero_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x80},
  {0xfe, 0x02},
	{0xd5, 0x00},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_pos1_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0x98},
	{0xfe, 0x02},
	{0xd5, 0x10},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_pos2_regs[] =
{
	{0xfe, 0x01},
	{0x13, 0xb0},
	{0xfe, 0x02},
	{0xd5, 0x20},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_pos3_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0xc0},
	{0xfe, 0x02},
	{0xd5, 0x30},
	{0xfe, 0x00},
};

static struct regval_list sensor_ev_pos4_regs[] =
{
  {0xfe, 0x01},
	{0x13, 0xd0},
	{0xfe, 0x02},
	{0xd5, 0x50},
	{0xfe, 0x00},
};

static struct cfg_array sensor_ev[] =
{
  {
  	.regs = sensor_ev_neg4_regs,
  	.size = ARRAY_SIZE(sensor_ev_neg4_regs),
  },
  {
  	.regs = sensor_ev_neg3_regs,
  	.size = ARRAY_SIZE(sensor_ev_neg3_regs),
  },
  {
  	.regs = sensor_ev_neg2_regs,
  	.size = ARRAY_SIZE(sensor_ev_neg2_regs),
  },
  {
  	.regs = sensor_ev_neg1_regs,
  	.size = ARRAY_SIZE(sensor_ev_neg1_regs),
  },
  {
  	.regs = sensor_ev_zero_regs,
  	.size = ARRAY_SIZE(sensor_ev_zero_regs),
  },
  {
  	.regs = sensor_ev_pos1_regs,
  	.size = ARRAY_SIZE(sensor_ev_pos1_regs),
  },
  {
  	.regs = sensor_ev_pos2_regs,
  	.size = ARRAY_SIZE(sensor_ev_pos2_regs),
  },
  {
  	.regs = sensor_ev_pos3_regs,
  	.size = ARRAY_SIZE(sensor_ev_pos3_regs),
  },
  {
  	.regs = sensor_ev_pos4_regs,
  	.size = ARRAY_SIZE(sensor_ev_pos4_regs),
  },
};

/*
 * Here we'll try to encapsulate the changes for just the output
 * video format.
 *
 */
static struct regval_list sensor_fmt_yuv422_yuyv[] =
{
	{0x84, 0x02}, //output put foramat
};

static struct regval_list sensor_fmt_yuv422_yvyu[] =
{
	{0x84, 0x03}, //output put foramat
};

static struct regval_list sensor_fmt_yuv422_vyuy[] =
{
	{0x84, 0x01}, //output put foramat
};

static struct regval_list sensor_fmt_yuv422_uyvy[] =
{
	{0x84, 0x00}, //output put foramat
};

static struct regval_list sensor_fmt_raw[] =
{
	{0x84, 0x18}, //output put foramat
};

//misc
static struct regval_list sensor_oe_disable_regs[] =
{
	//{0x3002,0x00},
  //{REG_TERM,VAL_TERM},
};

static struct regval_list sensor_oe_enable_regs[] =
{
  //{0x3002,0xe4},
  //{REG_TERM,VAL_TERM},
};

/*
 * Store information about the video data format.
 */
static struct sensor_format_struct
{
	__u8 *desc;
	//__u32 pixelformat;
	enum v4l2_mbus_pixelcode mbus_code;//linux-3.0
	struct regval_list *regs;
	int	regs_size;
	int bpp;   /* Bytes per pixel */
} sensor_formats[] = {
  {
		.desc		= "UYVY 4:2:2",
		.mbus_code	= V4L2_MBUS_FMT_UYVY8_2X8,//linux-3.0
		.regs 		= sensor_fmt_yuv422_uyvy,
		.regs_size = ARRAY_SIZE(sensor_fmt_yuv422_uyvy),
		.bpp		= 2,
	},
	{
		.desc		= "YUYV 4:2:2",
		.mbus_code	= V4L2_MBUS_FMT_YUYV8_2X8,//linux-3.0
		.regs 		= sensor_fmt_yuv422_yuyv,
		.regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yuyv),
		.bpp		= 2,
	},
	{
		.desc		= "YVYU 4:2:2",
		.mbus_code	= V4L2_MBUS_FMT_YVYU8_2X8,//linux-3.0
		.regs 		= sensor_fmt_yuv422_yvyu,
		.regs_size = ARRAY_SIZE(sensor_fmt_yuv422_yvyu),
		.bpp		= 2,
	},
	{
		.desc		= "VYUY 4:2:2",
		.mbus_code	= V4L2_MBUS_FMT_VYUY8_2X8,//linux-3.0
		.regs 		= sensor_fmt_yuv422_vyuy,
		.regs_size = ARRAY_SIZE(sensor_fmt_yuv422_vyuy),
		.bpp		= 2,
	},
  // NOTE: when trying set fmt, like V4L2_PIX_FMT_{BGR24,SGBRG8}, driver sets BGGR 8bits format and causes segmentation fault
	// {
	// 	.desc		= "RAW Bayer BGGR 8bit",
	// 	.mbus_code	= V4L2_MBUS_FMT_SBGGR8_1X8,//linux-3.0
	// 	.regs 		= sensor_fmt_raw,
	// 	.regs_size = ARRAY_SIZE(sensor_fmt_raw),
	// 	.bpp		= 1
	// },
};
#define N_FMTS ARRAY_SIZE(sensor_formats)

/*
 * Store information about resolutions mode support.
 */
static struct sensor_resolutions_struct
{
	struct regval_list *regs;
  struct sensor_win_size *win_sizes;
  int nwin_sizes;
  int nsize;
  int framerate;
  int mclk;
} sensor_resolutions[] = {
  {
		.regs		    = sensor_default_regs_hres0,
		.win_sizes	= sensor_win_sizes_hres0,
		.nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres0)),
		.nsize		  = ARRAY_SIZE(sensor_default_regs_hres0),
    .framerate  = 8,
    .mclk       = 24,
	},
  {
		.regs		    = sensor_default_regs_hres1,
		.win_sizes	= sensor_win_sizes_hres1,
		.nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres1)),
		.nsize		  = ARRAY_SIZE(sensor_default_regs_hres1),
    .framerate  = 10,
    .mclk       = 24,
	},
  {
		.regs		    = sensor_default_regs_hres2,
		.win_sizes	= sensor_win_sizes_hres2,
		.nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres2)),
		.nsize		  = ARRAY_SIZE(sensor_default_regs_hres2),
    .framerate  = 15,
    .mclk       = 24,
	},
  {
		.regs		    = sensor_default_regs_hres3,
		.win_sizes	= sensor_win_sizes_hres3,
		.nwin_sizes = (ARRAY_SIZE(sensor_win_sizes_hres3)),
		.nsize		  = ARRAY_SIZE(sensor_default_regs_hres3),
    .framerate  = 20,
    .mclk       = 34,
	},
};
#define N_RESOLUTIONS ARRAY_SIZE(sensor_resolutions)

/*
 * Low-level register I/O.
 *
 */

/*
 * On most platforms, we'd rather do straight i2c I/O.
 */
static int sensor_read(struct v4l2_subdev *sd, unsigned char reg,
    unsigned char *value) //!!!!be careful of the para type!!!
{
	int ret = 0;
	int cnt = 0;

  ret = cci_read_a8_d8(sd,reg,value);
  while (ret !=0 && cnt < 2)
  {
  	ret = cci_read_a8_d8(sd,reg,value);
  	cnt++;
  }
  if (cnt > 0)
  	vfe_dev_dbg("sensor read retry=%d\n",cnt);

  return ret;
}

static int sensor_write(struct v4l2_subdev *sd, unsigned short reg,
    unsigned char value)
{
	int ret = 0;
	int cnt = 0;
	ret = cci_write_a8_d8(sd,reg,value);
	while (ret !=0 && cnt < 2)
	{
		ret = cci_write_a8_d8(sd,reg,value);
		cnt++;
	}
	if (cnt > 0)
		vfe_dev_dbg("sensor write retry=%d\n",cnt);

	return ret;
}


/*
 * Write a list of register settings;
 */
static int sensor_write_array(struct v4l2_subdev *sd, struct regval_list *regs, int array_size)
{
	int i = 0;

  if (!regs) return -EINVAL;

  while (i < array_size)
  {
    if (regs->addr == REG_DLY)
    {
      msleep(regs->data);
    }
    else
    {
    	//printk("write 0x%x=0x%x\n", regs->addr, regs->data);
      LOG_ERR_RET(sensor_write(sd, regs->addr, regs->data))
    }
    i++;
    regs++;
  }
  return 0;
}


static int sensor_g_hflip(struct v4l2_subdev *sd, __s32 *value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_g_hflip!\n");
		return ret;
	}

	ret = sensor_read(sd, 0x17, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_g_hflip!\n");
		return ret;
	}

	val &= (1<<0);
	val = val>>0;		//0x29 bit0 is mirror

	*value = val;

	info->hflip = *value;
	return 0;
}

static int sensor_s_hflip(struct v4l2_subdev *sd, int value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_hflip!\n");
		return ret;
	}
	ret = sensor_read(sd, 0x17, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_s_hflip!\n");
		return ret;
	}

	switch (value)
  {
		case 0:
		  val &= 0xfe;
			break;
		case 1:
			val |= 0x01;
			break;
		default:
			return -EINVAL;
	}
	ret = sensor_write(sd, 0x17, val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_hflip!\n");
		return ret;
	}

	usleep_range(20000,22000);

	info->hflip = value;
	return 0;
}

static int sensor_g_vflip(struct v4l2_subdev *sd, __s32 *value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_g_vflip!\n");
		return ret;
	}

	ret = sensor_read(sd, 0x17, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_g_vflip!\n");
		return ret;
	}

	val &= (1<<1);
	val = val>>1;		//0x29 bit1 is upsidedown

	*value = val;

	info->vflip = *value;
	return 0;
}

static int sensor_s_vflip(struct v4l2_subdev *sd, int value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_vflip!\n");
		return ret;
	}

	ret = sensor_read(sd, 0x17, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_s_vflip!\n");
		return ret;
	}

	switch (value)
  {
		case 0:
		  val &= 0xfd;
			break;
		case 1:
			val |= 0x02;
			break;
		default:
			return -EINVAL;
	}

	ret = sensor_write(sd, 0x17, val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_vflip!\n");
		return ret;
	}

	usleep_range(20000,22000);

	info->vflip = value;
	return 0;
}

static int sensor_g_autogain(struct v4l2_subdev *sd, __s32 *value)
{
	return -EINVAL;
}

static int sensor_s_autogain(struct v4l2_subdev *sd, int value)
{
	return -EINVAL;
}

static int sensor_g_autoexp(struct v4l2_subdev *sd, __s32 *value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_g_autoexp!\n");
		return ret;
	}

	ret = sensor_read(sd, 0xb6, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_g_autoexp!\n");
		return ret;
	}

	val &= 0x01;
	if (val == 0x01)
  {
		*value = V4L2_EXPOSURE_AUTO;
	}
	else
	{
		*value = V4L2_EXPOSURE_MANUAL;
	}

	info->autoexp = *value;
	return 0;
}

static int sensor_s_autoexp(struct v4l2_subdev *sd,
		enum v4l2_exposure_auto_type value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_autoexp!\n");
		return ret;
	}

	ret = sensor_read(sd, 0xb6, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_s_autoexp!\n");
		return ret;
	}

	switch (value)
  {
		case V4L2_EXPOSURE_AUTO:
		  val |= 0x01;
			break;
		case V4L2_EXPOSURE_MANUAL:
			val &= 0xfe;
			break;
		case V4L2_EXPOSURE_SHUTTER_PRIORITY:
			return -EINVAL;
		case V4L2_EXPOSURE_APERTURE_PRIORITY:
			return -EINVAL;
		default:
			return -EINVAL;
	}

	//ret = sensor_write(sd, 0xb6, val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_autoexp!\n");
		return ret;
	}

	usleep_range(10000,12000);
	info->autoexp = value;
	return 0;
}

static int sensor_g_autowb(struct v4l2_subdev *sd, int *value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write(sd, 0xfe, 0x00);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_g_autowb!\n");
		return ret;
	}

	ret = sensor_read(sd, 0x82, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_g_autowb!\n");
		return ret;
	}

	val &= (1<<1);
	val = val>>1;		//0x42 bit1 is awb enable

	*value = val;
	info->autowb = *value;
	return 0;
}

static int sensor_s_autowb(struct v4l2_subdev *sd, int value)
{
	int ret;
	struct sensor_info *info = to_state(sd);
//	struct regval_list regs;
	unsigned char val;

	ret = sensor_write_array(sd, sensor_wb_auto_regs, ARRAY_SIZE(sensor_wb_auto_regs));
	if (ret < 0)
  {
		vfe_dev_err("sensor_write_array err at sensor_s_autowb!\n");
		return ret;
	}

	ret = sensor_read(sd, 0x82, &val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_read err at sensor_s_autowb!\n");
		return ret;
	}

	switch(value)
  {
	case 0:
		val &= 0xfd;
		break;
	case 1:
		val |= 0x02;
		break;
	default:
		break;
	}
	ret = sensor_write(sd, 0x82, val);
	if (ret < 0)
  {
		vfe_dev_err("sensor_write err at sensor_s_autowb!\n");
		return ret;
	}

	usleep_range(10000,12000);
	info->autowb = value;
	return 0;
}

static int sensor_g_hue(struct v4l2_subdev *sd, __s32 *value)
{
	return -EINVAL;
}

static int sensor_s_hue(struct v4l2_subdev *sd, int value)
{
	return -EINVAL;
}

static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
{
	return -EINVAL;
}

static int sensor_s_gain(struct v4l2_subdev *sd, int value)
{
	return -EINVAL;
}

/* *********************************************end of ******************************************** */

static int sensor_g_brightness(struct v4l2_subdev *sd, __s32 *value)
{
  struct sensor_info *info = to_state(sd);
  *value = info->brightness;
  return 0;
}

static int sensor_s_brightness(struct v4l2_subdev *sd, int value)
{
  struct sensor_info *info = to_state(sd);

  if(info->brightness == value)
    return 0;

  if(value < -4 || value > 4)
    return -ERANGE;

  LOG_ERR_RET(sensor_write_array(sd, sensor_brightness[value+4].regs, sensor_brightness[value+4].size))

  info->brightness = value;
  return 0;
}

static int sensor_g_contrast(struct v4l2_subdev *sd, __s32 *value)
{
  struct sensor_info *info = to_state(sd);
  *value = info->contrast;
  return 0;
}

static int sensor_s_contrast(struct v4l2_subdev *sd, int value)
{
  struct sensor_info *info = to_state(sd);

  if (info->contrast == value) return 0;

  if (value < -4 || value > 4) return -ERANGE;

  LOG_ERR_RET(sensor_write_array(sd, sensor_contrast[value+4].regs, sensor_contrast[value+4].size))

  info->contrast = value;
  return 0;
}

static int sensor_g_saturation(struct v4l2_subdev *sd, __s32 *value)
{
  struct sensor_info *info = to_state(sd);
  *value = info->saturation;
  return 0;
}

static int sensor_s_saturation(struct v4l2_subdev *sd, int value)
{
  struct sensor_info *info = to_state(sd);

  if (info->saturation == value) return 0;

  if(value < -4 || value > 4) return -ERANGE;

  LOG_ERR_RET(sensor_write_array(sd, sensor_saturation[value+4].regs, sensor_saturation[value+4].size))

  info->saturation = value;
  return 0;
}

static int sensor_g_exp_bias(struct v4l2_subdev *sd, __s32 *value)
{
  struct sensor_info *info = to_state(sd);
  *value = info->exp_bias;
  return 0;
}

static int sensor_s_exp_bias(struct v4l2_subdev *sd, int value)
{
  struct sensor_info *info = to_state(sd);

  if(info->exp_bias == value) return 0;

  if(value < -4 || value > 4) return -ERANGE;

  LOG_ERR_RET(sensor_write_array(sd, sensor_ev[value+4].regs, sensor_ev[value+4].size))

  info->exp_bias = value;
  return 0;
}

static int sensor_g_wb(struct v4l2_subdev *sd, int *value)
{
  struct sensor_info *info = to_state(sd);
  enum v4l2_auto_n_preset_white_balance *wb_type = (enum v4l2_auto_n_preset_white_balance*)value;

  *wb_type = info->wb;

  return 0;
}

static int sensor_s_wb(struct v4l2_subdev *sd,
    enum v4l2_auto_n_preset_white_balance value)
{
  struct sensor_info *info = to_state(sd);

  if (info->capture_mode == V4L2_MODE_IMAGE) return 0;

  if (info->wb == value) return 0;

  LOG_ERR_RET(sensor_write_array(sd, sensor_wb[value].regs ,sensor_wb[value].size) )

  if (value == V4L2_WHITE_BALANCE_AUTO)
  {
    info->autowb = 1;
  } else {
    info->autowb = 0;
  }

	info->wb = value;
	return 0;
}

static int sensor_g_colorfx(struct v4l2_subdev *sd, __s32 *value)
{
	struct sensor_info *info = to_state(sd);
	enum v4l2_colorfx *clrfx_type = (enum v4l2_colorfx*)value;

	*clrfx_type = info->clrfx;
	return 0;
}

static int sensor_s_colorfx(struct v4l2_subdev *sd, enum v4l2_colorfx value)
{
  struct sensor_info *info = to_state(sd);

  if(info->clrfx == value)
    return 0;

  LOG_ERR_RET(sensor_write_array(sd, sensor_colorfx[value].regs, sensor_colorfx[value].size))

  info->clrfx = value;
  return 0;
}

static int sensor_g_flash_mode(struct v4l2_subdev *sd, __s32 *value)
{
  struct sensor_info *info = to_state(sd);
  enum v4l2_flash_led_mode *flash_mode = (enum v4l2_flash_led_mode*)value;

  *flash_mode = info->flash_mode;
  return 0;
}

static int sensor_s_flash_mode(struct v4l2_subdev *sd, enum v4l2_flash_led_mode value)
{
  struct sensor_info *info = to_state(sd);
  info->flash_mode = value;
  return 0;
}

static int sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off)
{
	int ret = 0;
//	unsigned char rdval;
//
//	ret=sensor_read(sd, 0x00, &rdval);
//	if(ret!=0)
//		return ret;
//
//	if(on_off==CSI_STBY_ON)//sw stby on
//	{
//		ret=sensor_write(sd, 0x00, rdval&0x7f);
//	}
//	else//sw stby off
//	{
//		ret=sensor_write(sd, 0x00, rdval|0x80);
//	}
	return ret;
}

/*
 * Stuff that knows about the sensor.
 */

static int sensor_power(struct v4l2_subdev *sd, int on)
{
	int ret;

	cci_lock(sd);
	switch(on)
	{
	case CSI_SUBDEV_STBY_ON:
		vfe_dev_dbg("CSI_SUBDEV_STBY_ON\n");
		vfe_dev_print("disalbe oe!\n");
		ret = sensor_write_array(sd, sensor_oe_disable_regs, ARRAY_SIZE(sensor_oe_disable_regs));
		if(ret < 0)
			vfe_dev_err("disalbe oe falied!\n");
		ret = sensor_s_sw_stby(sd, CSI_STBY_ON);
		if(ret < 0)
			vfe_dev_err("soft stby falied!\n");
		vfe_gpio_write(sd,PWDN, CSI_GPIO_HIGH);
		usleep_range(10000,12000);
		vfe_set_mclk(sd,OFF);
		break;
	case CSI_SUBDEV_STBY_OFF:
		vfe_dev_dbg("CSI_SUBDEV_STBY_OFF\n");
		ret = sensor_s_sw_stby(sd, CSI_STBY_OFF);
		if(ret < 0)
			vfe_dev_err("soft stby off falied!\n");
		usleep_range(10000,12000);
		vfe_gpio_write(sd,PWDN, CSI_GPIO_LOW);
		usleep_range(10000,12000);
		//active mclk before stadby out
		vfe_set_mclk_freq(sd, (MCLK*1000*1000));
		vfe_set_mclk(sd,ON);
		usleep_range(10000,12000);
		vfe_dev_print("enable oe!\n");
		ret = sensor_write_array(sd, sensor_oe_enable_regs,  ARRAY_SIZE(sensor_oe_enable_regs));
		if(ret < 0)
		vfe_dev_err("enable oe falied!\n");
		break;
	case CSI_SUBDEV_PWR_ON:
		vfe_dev_dbg("CSI_SUBDEV_PWR_ON\n");
		vfe_gpio_set_status(sd,PWDN,1);//set the gpio to output
		vfe_gpio_set_status(sd,RESET,1);//set the gpio to output
		vfe_set_mclk_freq(sd,(MCLK*1000*1000));
		vfe_set_mclk(sd,ON);
		vfe_gpio_write(sd,PWDN, CSI_GPIO_LOW);
		vfe_gpio_write(sd,RESET, CSI_GPIO_LOW);
		vfe_gpio_write(sd,POWER_EN,CSI_PWR_ON);
		vfe_set_pmu_channel(sd,IOVDD,ON);
		vfe_set_pmu_channel(sd,AVDD,ON);
		vfe_set_pmu_channel(sd,DVDD,ON);
		vfe_set_pmu_channel(sd,AFVDD,ON);
		usleep_range(10000,12000);
		//reset after power on
		vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH);
		usleep_range(30000,31000);
		break;
	case CSI_SUBDEV_PWR_OFF:
		vfe_dev_dbg("CSI_SUBDEV_PWR_OFF\n");
		vfe_gpio_write(sd,PWDN,CSI_GPIO_LOW);
		vfe_gpio_write(sd,RESET,CSI_GPIO_LOW);
		usleep_range(5000,12000);
		vfe_gpio_write(sd,RESET,CSI_GPIO_HIGH);
		usleep_range(5000,12000);      //power supply off
		vfe_gpio_write(sd,PWDN,CSI_GPIO_HIGH);
		usleep_range(5000,12000);
		vfe_gpio_write(sd,RESET,CSI_GPIO_LOW);
		vfe_gpio_write(sd,POWER_EN,CSI_PWR_OFF);
		vfe_set_pmu_channel(sd,AFVDD,OFF);
		vfe_set_pmu_channel(sd,DVDD,OFF);
		vfe_set_pmu_channel(sd,AVDD,OFF);
		vfe_set_pmu_channel(sd,IOVDD,OFF);
		usleep_range(10000,12000);
		vfe_set_mclk(sd,OFF);
		vfe_gpio_set_status(sd,RESET,0);//set the gpio to input
		vfe_gpio_set_status(sd,PWDN,0);//set the gpio to input
		break;
	default:
		return -EINVAL;
	}
	cci_unlock(sd);
	return 0;
}

static int sensor_reset(struct v4l2_subdev *sd, u32 val)
{
  switch(val)
  {
    case 0:
      vfe_gpio_write(sd,RESET,CSI_RST_OFF);
      usleep_range(10000,12000);
      break;
    case 1:
      vfe_gpio_write(sd,RESET,CSI_RST_ON);
      usleep_range(10000,12000);
      break;
    default:
      return -EINVAL;
  }

  return 0;
}

static int sensor_detect(struct v4l2_subdev *sd)
{
	int ret;
	unsigned int SENSOR_ID = 0;
	unsigned char val;

//	ret = sensor_write(sd, 0xfe, 0x00);
//	if (ret < 0) {
//		vfe_dev_err("sensor_write err at sensor_detect!\n");
//		return ret;
//	}

	ret = sensor_read(sd, 0xf0, &val);
	SENSOR_ID|= (val<< 8);
	if (ret < 0) {
		vfe_dev_err("sensor_read err at sensor_detect!\n");
		return ret;
	}

	ret = sensor_read(sd, 0xf1, &val);
	SENSOR_ID |= (val);
	vfe_dev_print("V4L2_IDENT_SENSOR=%x",SENSOR_ID);
	if (ret < 0) {
		vfe_dev_err("sensor_read err at sensor_detect!\n");
		return ret;
	}

	if(SENSOR_ID != V4L2_IDENT_SENSOR)
		return -ENODEV;

	return 0;
}

static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
	int ret, nsize;
	vfe_dev_dbg("sensor_init\n");
	/*Make sure it is a target sensor*/
	ret = sensor_detect(sd);
	if (ret) {
		vfe_dev_err("chip found is not an target chip.\n");
		return ret;
	}

  nsize = sensor_resolutions[hres].nsize;
	ret = sensor_write_array(sd, sensor_default_regs , nsize);
	msleep(350);
  return 0;
}

static int sensor_g_exif(struct v4l2_subdev *sd, struct sensor_exif_attribute *exif)
{
	int ret = 0; //, gain_val, exp_val;
	unsigned  int temp = 0, shutter = 0, gain = 0;
	unsigned char val;

	sensor_write(sd, 0xfe, 0x00);
	//sensor_write(sd, 0xb6, 0x02);

	/*read shutter */
	sensor_read(sd, 0x03, &val);
	temp |= (val<< 8);
	sensor_read(sd, 0x04, &val);
	temp |= (val & 0xff);
	shutter = temp;

	sensor_read(sd, 0xb2, &val);
	gain = val;
	exif->fnumber = 280;
	exif->focal_length = 425;
	exif->brightness = 125;
	exif->flash_fire = 0;
	exif->iso_speed = 50*((50 + CLIP(gain-0x40, 0, 0xff)*5)/50);
	exif->exposure_time_num = 1;
	exif->exposure_time_den = 8000/shutter;
	return ret;
}

static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	int ret = 0;
	//struct sensor_info *info = to_state(sd);
	switch(cmd) {
		case GET_SENSOR_EXIF:
			sensor_g_exif(sd, (struct sensor_exif_attribute *)arg);
			break;
		default:
			return -EINVAL;
	}
	return ret;
}

static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned index, enum v4l2_mbus_pixelcode *code)
{
  if (index >= N_FMTS) return -EINVAL;
  *code = sensor_formats[index].mbus_code;
  return 0;
}

static int sensor_enum_size(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize)
{
  if (fsize->index > N_WIN_SIZES-1) return -EINVAL;

  fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
  fsize->discrete.width = sensor_win_sizes[fsize->index].width;
  fsize->discrete.height = sensor_win_sizes[fsize->index].height;
  return 0;
}

static int sensor_try_fmt_internal(struct v4l2_subdev *sd,
    struct v4l2_mbus_framefmt *fmt,
    struct sensor_format_struct **ret_fmt,
    struct sensor_win_size **ret_wsize)
{
  int index;
  struct sensor_win_size *wsize;

  for (index = 0; index < N_FMTS; index++)
  {
    if (sensor_formats[index].mbus_code == fmt->code) break;
  }

  if (index >= N_FMTS) return -EINVAL;

  if (ret_fmt != NULL) *ret_fmt = sensor_formats + index;

  /*
   * Fields: the sensor devices claim to be progressive.
   */

  fmt->field = V4L2_FIELD_NONE;

  // a try format
  // finds window format in all hres modes
  if (ret_fmt == NULL && ret_wsize == NULL)
  {
    int i;
    bool found_hres = false;
    struct sensor_resolutions_struct *res;
    for (i = 0; i < N_RESOLUTIONS-1; i++)
    {
      if (found_hres) break;
      res = &sensor_resolutions[i];
      for (index = 0; index < res->nwin_sizes; index++)
      {
          wsize = &res->win_sizes[index];
          if (fmt->width == wsize->width && fmt->height == wsize->height)
          {
              vfe_dev_dbg("%s Found hres: %d / resolution: %dx%d\n", __func__, i, fmt->width, fmt->height);
              found_hres = true;
              break;
           }
       }
    }
  }
  // set window size
  else
  {
    /*
     * Round requested image size down to the nearest
     * we support, but not below the smallest.
     */
    for (wsize = sensor_win_sizes; wsize < sensor_win_sizes + N_WIN_SIZES; wsize++)
    {
      if (fmt->width >= wsize->width && fmt->height >= wsize->height) break;
    }

    /* Take the smallest one */
    if (wsize >= sensor_win_sizes + N_WIN_SIZES) wsize--;

    if (ret_wsize != NULL) *ret_wsize = wsize;
  }

  /*
   * Note the size we'll actually handle.
   */
  fmt->width = wsize->width;
  fmt->height = wsize->height;

  return 0;
}

static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
{
  return sensor_try_fmt_internal(sd, fmt, NULL, NULL);
}

static int sensor_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg)
{
  cfg->type = V4L2_MBUS_PARALLEL;
  cfg->flags = V4L2_MBUS_MASTER | VREF_POL | HREF_POL | CLK_POL ;
  return 0;
}

/* Sets a window size
*/
static int sensor_s_wsize(struct v4l2_subdev *sd,
                          struct sensor_format_struct *sensor_fmt,
                          struct sensor_win_size *wsize)
{
  int ret;
  unsigned int temp = 0, shutter = 0;
  unsigned char val;

  if (hres == 1 || hres == 3)
  {
    if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT))
    {
      sensor_write(sd, 0xfe, 0x00);
      sensor_write(sd, 0xb6, 0x02);

      /*read shutter */
      sensor_read(sd, 0x03, &val);
      temp |= (val<< 8);

      sensor_read(sd, 0x04, &val);
      temp |= (val & 0xff);
      shutter = temp;
    }
  }

  if (sensor_fmt == NULL)
  {
    struct sensor_info *info = to_state(sd);
    sensor_fmt = info->fmt;
  }
  sensor_write_array(sd, sensor_fmt->regs , sensor_fmt->regs_size);

  ret = 0;
  if (wsize->regs)
  {
    ret = sensor_write_array(sd, wsize->regs , wsize->regs_size);
    if (ret < 0)
      return ret;
  }

  if (wsize->set_size)
  {
    ret = wsize->set_size(sd);
    if (ret < 0)
      return ret;
  }

  if (hres == 0)
  {
     if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT))
     {
          sensor_write(sd, 0xfe, 0x00);
          sensor_write(sd, 0xb6, 0x03);  // AEC ON
          sensor_write(sd, 0xfa, 0x08);  // clk div mode
          sensor_read(sd, 0x03, &val);
          temp |= (val<< 8);
          sensor_read(sd, 0x04, &val);
          temp |= (val & 0xff);
          shutter = temp;
          shutter = shutter / 2;
          if (shutter < 1) shutter = 1;
          val = ((shutter>>8) & 0xff);
          sensor_write(sd, 0x03, val);
          val = (shutter & 0xff);
          sensor_write(sd, 0x04, val);
          msleep(550);
     }

     else if ((wsize->width == VGA_WIDTH && wsize->height == VGA_HEIGHT) ||
          (wsize->width == HD720_WIDTH && wsize->height == HD720_HEIGHT))
     {
           mdelay(50);
           sensor_write(sd, 0xb6, 0x03);  // AEC ON

           if (wsize->width == HD720_WIDTH && wsize->height == HD720_HEIGHT)
           {
             sensor_write(sd, 0xfa, 0x08); // clk div mode
           }
           mdelay(300);
     }
  }

  else if (hres == 1)
  {
      if ((wsize->width == UXGA_WIDTH) && (wsize->height == UXGA_HEIGHT))
      {
          sensor_write(sd, 0xfe, 0x00);
          sensor_write(sd, 0xb6, 0x03);  // AEC ON
          sensor_write(sd, 0xfa, 0x08);  // clk div mode

          shutter = shutter / 2;
          if(shutter < 1) shutter = 1;
          val = ((shutter>>8)&0xff);
          sensor_write(sd, 0x03, val);
          val = (shutter&0xff);
          sensor_write(sd, 0x04, val);
          msleep(550);
      }
  }

  else if (hres == 2)
  {

    sensor_write(sd, 0xfe, 0x01);
    sensor_write(sd, 0x21, 0xbf);
    sensor_write(sd, 0xfe, 0x00);

    sensor_write(sd, 0x03, 0);
    sensor_write(sd, 0x04, 0);

    sensor_write(sd, 0xb6, 0x03);
    sensor_write(sd, 0xfa, 0x00);

    if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT))
    {
        sensor_write(sd, 0xc8, 0x02);
        sensor_write(sd, 0x99, 0x44);
    }

    else if ((wsize->width == CIF_WIDTH && wsize->height == CIF_HEIGHT))
    {
        sensor_write(sd, 0xc8, 0x03);
        sensor_write(sd, 0x99, 0x44);
    }

    else if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT))
    {
        sensor_write(sd, 0xc8, 0x00);
        sensor_write(sd, 0x99, 0x22);
    }

    sensor_write(sd, 0x9a, 0x07);
    sensor_write(sd, 0x9b, 0x00);
    sensor_write(sd, 0x9c, 0x00);
    sensor_write(sd, 0x9d, 0x00);
    sensor_write(sd, 0x9e, 0x00);
    sensor_write(sd, 0x9f, 0x00);

    sensor_write(sd, 0xa1, 0x00);
    sensor_write(sd, 0xa2, 0x00);

    sensor_write(sd, 0x90, 0x01); // crop enable
    sensor_write(sd, 0x94, 0x02);
    sensor_write(sd, 0x95, 0x02);

    if ((wsize->width == QVGA_WIDTH && wsize->height == QVGA_HEIGHT) ||
        (wsize->width == CIF_WIDTH && wsize->height == CIF_HEIGHT))
    {
        sensor_write(sd, 0x96, 0x58);
    } else
    {
      sensor_write(sd, 0x96, 0x5a);
    }

    sensor_write(sd, 0x97, 0x03);
    sensor_write(sd, 0x98, 0x22);
    mdelay(50);
  }

  return 0;
}

/*
 * Set a format.
*/
static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)//linux-3.0
{
	int ret;
	struct sensor_format_struct *sensor_fmt;
	struct sensor_win_size *wsize;
	struct sensor_info *info = to_state(sd);

  int i, nsize, index;
  bool found_hres = false;
  struct sensor_resolutions_struct *res;
  for (i = 0; i < N_RESOLUTIONS-1; i++)
  {
    if (found_hres) break;
    res = &sensor_resolutions[i];
    for (index = 0; index < res->nwin_sizes; index++)
    {
        wsize = &res->win_sizes[index];
        if (fmt->width == wsize->width && fmt->height == wsize->height)
        {
            found_hres = true;
            if (hres != i)
            {
              vfe_dev_dbg("%s Change hres %d to: %d\n", __func__, hres, i);
              hres = i;
              sensor_default_regs = res->regs;
              sensor_win_sizes = res->win_sizes;
              N_WIN_SIZES = res->nwin_sizes;
              nsize = res->nsize;
              if (!frate) SENSOR_FRAME_RATE = res->framerate;

              if ((res->mclk != MCLK) && !mclk)
              {
                MCLK = res->mclk;
                vfe_dev_dbg("%s Change mclk: %d\n", __func__, MCLK*1000*10000);
                vfe_set_mclk_freq(sd, (MCLK*1000*1000));
                vfe_set_mclk(sd, ON);
                usleep_range(10000, 12000);
              }

              ret = sensor_write_array(sd, sensor_default_regs, nsize);
              msleep(350);
            }
            break;
         }
     }
  }

  ret = sensor_try_fmt_internal(sd, fmt, &sensor_fmt, &wsize);
  if (ret)
    return ret;

  ret = sensor_s_wsize(sd, sensor_fmt, wsize);
  if (ret < 0)
    return ret;

  sensor_s_hflip(sd,info->hflip);
  sensor_s_vflip(sd,info->vflip);

  info->fmt = sensor_fmt;
  info->width = wsize->width;
  info->height = wsize->height;

  return 0;
}

/*
 * Implement G/S_PARM.  There is a "high quality" mode we could try
 * to do someday; for now, we just do the frame rate tweak.
 */
static int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
	struct v4l2_captureparm *cp = &parms->parm.capture;

	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL;

	memset(cp, 0, sizeof(struct v4l2_captureparm));
	cp->capability = V4L2_CAP_TIMEPERFRAME;
	cp->timeperframe.numerator = 1;
	cp->timeperframe.denominator = SENSOR_FRAME_RATE;
	return 0;
}

static int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
	struct v4l2_captureparm *cp = &parms->parm.capture;
	struct sensor_info *info = to_state(sd);
	struct v4l2_fract *tpf = &cp->timeperframe;
  int div, clkrc;
  clkrc = 1;

	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL;
	if (cp->extendedmode != 0) return -EINVAL;

  if (tpf->denominator != SENSOR_FRAME_RATE)
  {
    int index, i, ret;
    // finds compatible framerate
    for (index = 0; index < N_RESOLUTIONS-1; index++)
    {
      if (sensor_resolutions[index].framerate >= tpf->denominator) break;
    }

    if (hres != index)
    {
      // checks if exists resolution compatible with selected framerate
      struct sensor_resolutions_struct *res;
      struct sensor_win_size *wsize;
      res = &sensor_resolutions[index];
      int nsize;

      for (i = 0; i < res->nwin_sizes; i++)
      {

        wsize = &res->win_sizes[i];
        if (info->width == wsize->width && info->height == wsize->height)
        {
          vfe_dev_dbg("%s Change hres %d to: %d\n", __func__, hres, index);
          hres = index;
          sensor_default_regs = res->regs;
          sensor_win_sizes = res->win_sizes;
          N_WIN_SIZES = res->nwin_sizes;
          nsize = res->nsize;
          SENSOR_FRAME_RATE = res->framerate;

          if ((res->mclk != MCLK) && !mclk)
          {
            MCLK = res->mclk;
            vfe_dev_dbg("%s Change mclk: %d\n", __func__, MCLK*1000*10000);
            vfe_set_mclk_freq(sd, (MCLK*1000*1000));
            vfe_set_mclk(sd, ON);
            usleep_range(10000, 12000);
          }

          ret = sensor_write_array(sd, sensor_default_regs, nsize);
          if (ret < 0)
            return ret;
          msleep(350);

          ret = sensor_s_wsize(sd, NULL, wsize);
          if (ret < 0)
            return ret;

          break;
        }

      }

    }

  }

  // reset to full framerate
  tpf->numerator = 0;

	if (tpf->numerator == 0 || tpf->denominator == 0)
  {
    div = 1;  // Reset to full rate
  }
  else
  {
    div = (tpf->numerator*SENSOR_FRAME_RATE)/tpf->denominator;
  }

  if (div == 0) div = 1;
  else if (div > 8) div = 8;

  clkrc = (clkrc & 0x80) | div;
  tpf->numerator = 1;
  tpf->denominator = SENSOR_FRAME_RATE / div;
  sensor_write(sd, REG_CLKRC, clkrc);
  return 0;
}


/*
 * Code for dealing with controls.
 * fill with different sensor module
 * different sensor module has different settings here
 * if not support the follow function ,retrun -EINVAL
 */

/* *********************************************begin of ******************************************** */
static int sensor_queryctrl(struct v4l2_subdev *sd,
		struct v4l2_queryctrl *qc)
{
	/* Fill in min, max, step and default value for these controls. */
	/* see include/linux/videodev2.h for details */
	/* see sensor_s_parm and sensor_g_parm for the meaning of value */
	switch (qc->id) {
	case V4L2_CID_BRIGHTNESS:
		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1);

	case V4L2_CID_CONTRAST:
		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1);

	case V4L2_CID_SATURATION:
		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 1);

	case V4L2_CID_HUE:
		return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);

	case V4L2_CID_VFLIP:
	case V4L2_CID_HFLIP:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);

	case V4L2_CID_GAIN:
		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);

	case V4L2_CID_AUTOGAIN:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);

	case V4L2_CID_EXPOSURE:
  case V4L2_CID_AUTO_EXPOSURE_BIAS:
		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 0);

	case V4L2_CID_EXPOSURE_AUTO:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);

  case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
    return v4l2_ctrl_query_fill(qc, 0, 9, 1, 1);

	case V4L2_CID_AUTO_WHITE_BALANCE:
		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);

	case V4L2_CID_COLORFX:
    return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0);
  case V4L2_CID_FLASH_LED_MODE:
	  return v4l2_ctrl_query_fill(qc, 0, 4, 1, 0);

  case V4L2_CID_3A_LOCK:
   return v4l2_ctrl_query_fill(qc, 0, V4L2_LOCK_EXPOSURE |
                                      V4L2_LOCK_WHITE_BALANCE |
                                      V4L2_LOCK_FOCUS, 1, 0);
  case V4L2_CID_AUTO_FOCUS_RANGE:
   return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);//only auto

  case V4L2_CID_AUTO_FOCUS_STATUS:
   return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);

  case V4L2_CID_FOCUS_AUTO:
   return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);

  case V4L2_CID_AUTO_EXPOSURE_WIN_NUM:
   return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);

  case V4L2_CID_AUTO_FOCUS_WIN_NUM:
   return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
	}
	return -EINVAL;
}


static int sensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		return sensor_g_brightness(sd, &ctrl->value);

	case V4L2_CID_CONTRAST:
		return sensor_g_contrast(sd, &ctrl->value);

	case V4L2_CID_SATURATION:
		return sensor_g_saturation(sd, &ctrl->value);

	case V4L2_CID_HUE:
		return sensor_g_hue(sd, &ctrl->value);

	case V4L2_CID_VFLIP:
		return sensor_g_vflip(sd, &ctrl->value);

	case V4L2_CID_HFLIP:
		return sensor_g_hflip(sd, &ctrl->value);

	case V4L2_CID_GAIN:
		return sensor_g_gain(sd, &ctrl->value);

	case V4L2_CID_AUTOGAIN:
		return sensor_g_autogain(sd, &ctrl->value);

	case V4L2_CID_EXPOSURE:

  case V4L2_CID_AUTO_EXPOSURE_BIAS:
    return sensor_g_exp_bias(sd, &ctrl->value);

  case V4L2_CID_EXPOSURE_AUTO:
    return sensor_g_autoexp(sd, &ctrl->value);

  case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
    return sensor_g_wb(sd, &ctrl->value);

  case V4L2_CID_AUTO_WHITE_BALANCE:
    return sensor_g_autowb(sd, &ctrl->value);

  case V4L2_CID_COLORFX:
    return sensor_g_colorfx(sd, &ctrl->value);

  case V4L2_CID_FLASH_LED_MODE:
    return sensor_g_flash_mode(sd, &ctrl->value);
	}
	return -EINVAL;
}

static int sensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
  struct v4l2_queryctrl qc;
  int ret;

  qc.id = ctrl->id;
  ret = sensor_queryctrl(sd, &qc);
  if (ret < 0) {
    return ret;
  }

	if (qc.type == V4L2_CTRL_TYPE_MENU ||
		qc.type == V4L2_CTRL_TYPE_INTEGER ||
		qc.type == V4L2_CTRL_TYPE_BOOLEAN)
	{
	  if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) {
	    return -ERANGE;
	  }
	}
	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		return sensor_s_brightness(sd, ctrl->value);

	case V4L2_CID_CONTRAST:
		return sensor_s_contrast(sd, ctrl->value);

	case V4L2_CID_SATURATION:
		return sensor_s_saturation(sd, ctrl->value);

	case V4L2_CID_HUE:
		return sensor_s_hue(sd, ctrl->value);

	case V4L2_CID_VFLIP:
		return sensor_s_vflip(sd, ctrl->value);

	case V4L2_CID_HFLIP:
		return sensor_s_hflip(sd, ctrl->value);

	case V4L2_CID_GAIN:
		return sensor_s_gain(sd, ctrl->value);

	case V4L2_CID_AUTOGAIN:
		return sensor_s_autogain(sd, ctrl->value);

	case V4L2_CID_EXPOSURE:
    case V4L2_CID_AUTO_EXPOSURE_BIAS:
      return sensor_s_exp_bias(sd, ctrl->value);

    case V4L2_CID_EXPOSURE_AUTO:
      return sensor_s_autoexp(sd,
          (enum v4l2_exposure_auto_type) ctrl->value);

    case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
  		return sensor_s_wb(sd,
          (enum v4l2_auto_n_preset_white_balance) ctrl->value);

    case V4L2_CID_AUTO_WHITE_BALANCE:
      return sensor_s_autowb(sd, ctrl->value);

    case V4L2_CID_COLORFX:
      return sensor_s_colorfx(sd,
          (enum v4l2_colorfx) ctrl->value);

    case V4L2_CID_FLASH_LED_MODE:
      return sensor_s_flash_mode(sd,
          (enum v4l2_flash_led_mode) ctrl->value);
	}
	return -EINVAL;
}


static int sensor_g_chip_ident(struct v4l2_subdev *sd,
		struct v4l2_dbg_chip_ident *chip)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SENSOR, 0);
}


/* ----------------------------------------------------------------------- */

static const struct v4l2_subdev_core_ops sensor_core_ops =
{
	.g_chip_ident = sensor_g_chip_ident,
	.g_ctrl = sensor_g_ctrl,
	.s_ctrl = sensor_s_ctrl,
	.queryctrl = sensor_queryctrl,
	.reset = sensor_reset,
	.init = sensor_init,
	.s_power = sensor_power,
	.ioctl = sensor_ioctl,
};

static const struct v4l2_subdev_video_ops sensor_video_ops =
{
  .enum_mbus_fmt = sensor_enum_fmt,
  .enum_framesizes = sensor_enum_size,
  .try_mbus_fmt = sensor_try_fmt,
  .s_mbus_fmt = sensor_s_fmt,
  .s_parm = sensor_s_parm,
  .g_parm = sensor_g_parm,
  .g_mbus_config = sensor_g_mbus_config,
};

static const struct v4l2_subdev_ops sensor_ops =
{
	.core = &sensor_core_ops,
	.video = &sensor_video_ops,
};

/* ----------------------------------------------------------------------- */
static struct cci_driver cci_drv =
{
	.name = SENSOR_NAME,
	.addr_width = CCI_BITS_8,
	.data_width = CCI_BITS_8,
};

static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct v4l2_subdev *sd;
	struct sensor_info *info;

	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
	if (info == NULL) return -ENOMEM;
	sd = &info->sd;
	cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv);

	if(client) client->addr = 0x78>>1;
	info->fmt = &sensor_formats[0];

	info->brightness = 0;
	info->contrast = 0;
	info->saturation = 0;
	info->hue = 0;
	info->hflip = 0;
	info->vflip = 0;
	info->gain = 0;
	info->autogain = 1;
	info->exp = 0;
	info->autoexp = 0;
	info->autowb = 1;
	info->wb = 0;
	info->clrfx = 0;
	//info->clkrc = 1;	/* 30fps */
	return 0;
}

static int sensor_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd;
	sd = cci_dev_remove_helper(client, &cci_drv);
	kfree(to_state(sd));
	return 0;
}

static const struct i2c_device_id sensor_id[] =
{
	{ SENSOR_NAME, 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, sensor_id);

//linux-3.0
static struct i2c_driver sensor_driver =
{
	.driver = {
		.owner = THIS_MODULE,
	.name = SENSOR_NAME,
	},
	.probe = sensor_probe,
	.remove = sensor_remove,
	.id_table = sensor_id,
};

static __init int init_sensor(void)
{
  if (mclk > 34) mclk = 0;
  sensor_default_regs = sensor_resolutions[hres].regs;
  sensor_win_sizes = sensor_resolutions[hres].win_sizes;
  N_WIN_SIZES = sensor_resolutions[hres].nwin_sizes;
  SENSOR_FRAME_RATE = sensor_resolutions[hres].framerate;
  MCLK = sensor_resolutions[hres].mclk;

  if (mclk) MCLK = mclk;

  if (frate) SENSOR_FRAME_RATE = frate;

	return cci_dev_init_helper(&sensor_driver);
}

static __exit void exit_sensor(void)
{
	cci_dev_exit_helper(&sensor_driver);
}

module_init(init_sensor);
module_exit(exit_sensor);
